-
Notifications
You must be signed in to change notification settings - Fork 1
intn
This driver is a further development from the one
driver. It implements additionally 2 features:
- store (write) data (integer) provided from user space
- implements basic concurrency
In other words, the user can set a desired value (integer) and more than one user space programm can read/write in a coherent way. In order to test this driver a user space programm was written additionally, where it can start n threads in parallel (default: 4) that read the driver value, increment it and write it back.
A struct
was created to gather all the related data structures:
struct intn2_dev {
struct cdev intn_cdev;
struct class *intn_class;
struct device *intn_device;
struct mutex intn_mutex;
};
The necessary header are the same as in the intn
driver.
We take care now the concurrency operations in the open
and release
functions, so we must deal with multiple user-space accesses. They are executed when the user-space invoke the open
and close
system calls respectively.
int intn2_release(struct inode *inode, struct file *filp)
{
mutex_unlock(&intn2->intn2_mutex);
return 0;
}
int intn2_open(struct inode *inode, struct file *filp)
{
mutex_lock(&intn2->intn2_mutex);
return 0;
}
Write
: write data from the device.
ssize_t (*read)(struct file *f, char __user *u, size_t size, loff_t *l);
Parameters | type | Description |
---|---|---|
*f | input | pointer to the structure that represents the file to be open |
*u | input | pointer to the buffer that stores data to be read from the device |
size | input | number of bytes to be read |
*l | input | pointer to the current reading position/offset |
ssize_t | return | a non-negative return value represents the number of bytes successfully read, on failure a negative error code |
The one_read
implements this operation, returning only a "1" to user-space. In order to do so, the copy_to_user
function is used. If an error occurs, an -EFAULT
is returned to user space.
unsigned long copy_from_user(void __user *to, const void *from, unsigned long count);
Parameters | type | Description |
---|---|---|
*to | output | pointer to the buffer in kernel space |
*from | input | pointer to the buffer holding the data in user space |
count | input | number of bytes to be copied from user-space |
unsigned long | return | returns zero on success or non-zero to indicate the number of bytes that weren't transferred |
Run make
and make test
to compile the driver and the user space test program. Run sudo make ins
or sudo insmod one.ko
to insert the driver in the Linux Kernel memory space. Then take a look at the kernel log and you should see the following line:
Jun 16 21:09:19 localhost kernel: [41443.956311] intn<Major, Minor>: <248, 0>
and also run lsmod
and the output should be like this:
% lsmod | grep intn
intn 14724 0
To read from /dev/intn
execute:
dd if=/dev/intn of=intn.txt bs=1 count=10
Open the intn.txt
file in an editor capable of show the hexadecimal representation and this should be ten 1's:
01 01 01 01 01 01 01 01 01 01
The same result as the one
driver. As we can run our test program:
./test_intn
TODO: finish this section
In the end remove the driver from the kernel using:
sudo rmmod intn.ko