Reputation: 49
I started studying char device drivers and encountered such a problem that with any attempt to interact with char device via read, write, ioctl, it writes "No such device or address". The device is created with the specified parameters, and a class of devices is also created.
logs from dmesg
[24102.683168] DBG: param in (struct data)
[24102.683169] DBG: struct transfer_string->buffer: 00000000dd1a65b0 && buffer: hello from kernel space!
[24102.683170] DBG: struct device_class: 18446614143144514304
[24102.683171] DBG: struct device_device: 0
[24102.683172] DBG: buffer_pos: 0
[24102.683172] DBG: struct data_dev: 18446614151544970752
[24102.683173] DBG: data_dev->dev: 527433729 | 503 : 1
[24102.683174] DBG: data_dev->major: 503
[24102.683175] DBG: data_dev->minor: 1
[24102.683176] DBG: data_dev->count: 0
[24102.683177] DBG: data_dev->module_name: my_ioc_device
[24102.683177] DBG: data->fops.open: 18446744072663138320
[24102.683178] DBG: data->fops.release: 18446744072663138384
[24102.683179] DBG: data->fops.read: 18446744072663140048
[24102.683180] DBG: data->fops.write: 18446744072663138432
[24102.683180] DBG: data->fops.unlocked_ioctl: 18446744072663138704
[24102.683181] DBG: ===================================================
[24102.683395] DBG: add char device
[24102.683395] INFO: ================== module installed 503:1 ==================
structure that logs
void logging_all_param(void)
{
DBG("===================================================\n");
DBG("param in (struct data)\n");
DBG("struct transfer_string->buffer: %p && buffer: %s\n", data->transfer_string->buffer, data->transfer_string->buffer);
DBG("struct device_class: %lu\n", (data->device_class != NULL) ? (uintptr_t)data->device_class : 0);
DBG("struct device_device: %lu\n", (data->device_device != NULL) ? (uintptr_t)data->device_device : 0);
DBG("buffer_pos: %lld\n", data->buffer_pos);
DBG("struct data_dev: %lu\n", (data->data_dev != NULL) ? (uintptr_t)data->data_dev : 0);
DBG("data_dev->dev: %d | %d : %d", data->data_dev->dev, MAJOR(data->data_dev->dev), MINOR(data->data_dev->dev));
DBG("data_dev->major: %d\n", MAJOR(data->data_dev->major));
DBG("data_dev->minor: %d\n", MINOR(data->data_dev->minor));
DBG("data_dev->count: %d\n", data->data_dev->count);
DBG("data_dev->module_name: %s\n\n", data->data_dev->module_name);
DBG("data->fops.open: %lu\n", (data->fops.open != NULL) ? (uintptr_t)data->fops.open : 0);
DBG("data->fops.release: %lu\n", (data->fops.release != NULL) ? (uintptr_t)data->fops.release : 0);
DBG("data->fops.read: %lu\n", (data->fops.read != NULL) ? (uintptr_t)data->fops.read : 0);
DBG("data->fops.write: %lu\n", (data->fops.write != NULL) ? (uintptr_t)data->fops.write : 0);
DBG("data->fops.unlocked_ioctl: %lu\n", (data->fops.unlocked_ioctl != NULL) ? (uintptr_t)data->fops.unlocked_ioctl : 0);
DBG("===================================================\n");
}
example of error:
jokkeu@jokkeu-host:/dev$ ls -la my_ioc_device
crw-------. 1 root root 503, 1 Mar 3 02:49 my_ioc_device
jokkeu@jokkeu-host:/dev$ sudo cat my_ioc_device
[sudo] password for jokkeu:
cat: my_ioc_device: No such device or address
also:
jokkeu@jokkeu-host:/sys/class/ioc_dev/my_ioc_device$ cd ..
jokkeu@jokkeu-host:/sys/class/ioc_dev$ ls -la
total 0
drwxr-xr-x. 2 root root 0 Mar 3 03:08 .
drwxr-xr-x. 76 root root 0 Mar 3 02:49 ..
lrwxrwxrwx. 1 root root 0 Mar 3 03:08 my_ioc_device -> ../../devices/virtual/ioc_dev/my_ioc_device
jokkeu@jokkeu-host:/sys/class/ioc_dev$ cd my_ioc_device/
jokkeu@jokkeu-host:/sys/class/ioc_dev/my_ioc_device$ ls
dev power subsystem uevent
jokkeu@jokkeu-host:/sys/class/ioc_dev/my_ioc_device$ cat dev
503:1
data sturct
struct _DEV
{
int32_t major;
int32_t minor;
int32_t count;
struct cdev hcdev;
dev_t dev;
char class_name[50];
char module_name[50];
};
struct _DATA
{
struct _TRANSFER_STRING* transfer_string;
struct class* device_class;
struct device* device_device;
loff_t buffer_pos;
struct _DEV* data_dev;
struct file_operations fops;
};
struct file_operations function:
ssize_t dev_read(struct file* file, char __user* buffer, size_t count, loff_t* ppos)
{
DBG("start dev_read\n");
LOGGING_ALL;
size_t ret_bytes = 0;
int ret;
if (!data || !data->transfer_string) { ERR("Data or transfer_string is NULL\n"); ret = -EFAULT; goto out;}
if (*ppos >= data->buffer_pos) { DBG("No more data to read\n"); return EOK; }
size_t bytes_to_read = min(count, data->buffer_pos - *ppos);
LOGGING_ALL;
DBG("bytes_to_read: %lu\n", bytes_to_read);
DBG("ppos: %lu\n", *ppos);
if (copy_to_user(buffer, data->transfer_string->buffer + *ppos, bytes_to_read))
{
ret = -EFAULT;
goto out;
}
ret_bytes += bytes_to_read;
*ppos += bytes_to_read;
DBG("=== read bytes: %ld\n=== buffer_pos: %llu\n=== ppos: %llu\n",
ret_bytes,
data->buffer_pos,
*ppos);
return ret_bytes;
out:
ERR("in dev_read: err = %d\n", ret);
return ret;
}
ssize_t dev_write(struct file* file, const char __user* buffer, size_t count, loff_t* ppos)
{
DBG("=== device write === \n");
if (!data || !data->transfer_string) { ERR("Data or transfer_string is NULL\n"); return -EFAULT; }
if (*ppos > BUFFER_SIZE - 1) {*ppos = BUFFER_SIZE - 1;}
if (copy_from_user(data->transfer_string->buffer, buffer, count)) {ERR("Failed to copy data from user\n"); return -EFAULT;}
data->transfer_string->buffer[count] = '\0';
data->buffer_pos = count;
DBG("=== device write end === \n");
return count;
}
int dev_open(struct inode* inode, struct file* file)
{
if (device_open)
{
return -EBUSY;
}
device_open++;
return EOK;
}
int dev_release(struct inode*, struct file* file)
{
device_open--;
return EOK;
}
Please tell me how to deal with this error. Thanks
Upvotes: 1
Views: 57