What is the significance of THIS_MODULE in Linux kernel module drivers? - linux

In Linux device driver development, the file_operations structure uses struct module *owner.
What is the use of this structure when we always initialize it with THIS_MODULE?
When can this field be set to NULL?

This field tells who is owner of struct file_operations. This prevents module to get unloaded when it is in operation. When initialized with THIS_MODULE current module holds the ownership on it.

Minimal runnable example
Whenever you create a kernel module, the kernel's build machinery generates a struct module object for you, and makes THIS_MODULE point to it.
This struct contains many fields, some of which can be set with module macros such as MODULE_VERSION.
This example shows how to access that information: module_info.c:
#include <linux/module.h>
#include <linux/kernel.h>
static int myinit(void)
{
/* Set by default based on the module file name. */
pr_info("name = %s\n", THIS_MODULE->name);
pr_info("version = %s\n", THIS_MODULE->version);
return 0;
}
static void myexit(void) {}
module_init(myinit)
module_exit(myexit)
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");
Dmesg outputs:
name = module_info
version = 1.0
Some MODULE_INFO fields can also be "accessed" in the following ways:
cat /sys/module/module_info/version
modinfo /module_info.ko | grep -E '^version:'
Since the address of that struct module object must be unique across all modules, it serves as a good argument for fops.owner as mentioned at: https://stackoverflow.com/a/19468893/895245. Here is a minimal example of that usage.
Tested in Linux kernel 4.16 with this QEMU + Buildroot setup.

[1] struct module *owner is commonly used at some structures and is not an operation at all; it is a pointer to the module that "owns"the structure. This field is used to prevent the module from being unloaded while its operations are in use. Almost all the time, it is simply initialized to THIS_MODULE, a macro defined in
< linux/module.h> .
.
[2] I would not recommend you to set it to null, because it may lead to driver malfunction and other problems. Instead, use the good practices of linux kernel development.
In some architectures the ".owner" was removed, so, make sure your distro and architecture still using it.
I hope it helps your understanding.
References: LDD3, kernel newbies.

file_operation is one of the main structures that used to connect the device numbers and the file operations of a driver.
There are lots of function pointer in the structure. The first pointer is struct module *owner which is not a function pointer at all but points to a structure module defined in the <linux/module.h>.
On initializing to THIS_MODULE, it holds the ownership of the module.
One of the main reasons to initialize struct module *owner to THIS_MODULE to prevent the module from getting unloaded while in use.

Related

Handling multiple i2c_clients in one driver module (with sysfs)

I want to create a kernel driver for tmp102 temperature sensors.
In one project I have only 1 sensor, in the other - 2 sensors. I want my kernel module to be able to support N sensors, not a fixed number. I have a problem with managing more than 1 struct i2c_client and creating sysfs entries for each of them. Here's how I'm doing it:
In the probe() function I get struct i2c_client* for each of the devices that I provide I2C_BOARD_INFO() for.
I then kobject_create_and_add("tmp102", kernel_kobj) to get the main directory for the modules in sysfs.
For each device I'm creating sysfs_create_group() which gets the pointer to statically created attributes. The attributes have the (*show)() and (*store)() pointers set to static functions, e.g.
static ssize_t tmp102_sysfs_thigh_get_one(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
In this function I want to read via I2C. The problem is... I don't know how to get the struct i2c_client * for the device which should be somehow linked to this sysfs entry, and the I2C address is there!
How should I properly "link" i2c_client with sysfs entries, so that I can get the I2C address inside the functions?
Ideally, I would like to have just one set of functions (one for each of the attributes). The sysfs tree should look like that:
/sysfs/kernel/tmp102
|
|-> <hex i2c address, e.g. /48>
| |
| |-> temperature
|
|
|-> /49
|
|-> temperature
I want both 'temperature' attributes to use the same function, which is able to determine the I2C address, to which it should write.
Or maybe my architecture is plain wrong? If so, how should it look like for a driver that needs to handle multiple i2c_clients?
EDIT:
I decided to use struct device_attribute instead of regular attributes. To my understanding, it is not easy to get the struct device pointer when using the regular attributes, same with struct i2c_client. They are not easily "linked" with kobjects from /sys/kernel, where I need to have my attributes for this project. device_attributes can be found in /sys/devices - I used sysfs_create_group and linked my device's kobject with the device_attribute group. I used sysfs_create_link, and linked my device's kobject with the /sys/kernel/tmp102. This way I could create a folder (link) for each of the devices, which points to the original attributes folder in /sys/devices.
First, you should know that there is already a kernel driver for the tmp102 that has a sysfs interface. Have a look at drivers/hwmon/tmp102.c.
Now, for your issue, you have a struct kobject that is passed to you sysfs callback. You can call kobj_to_dev() to get a pointer to the device. Then, for example, you could use dev_get_drvdata() to get a pointer to your own private structure that would contain a pointer to the i2c client. Don't forget to set it first with dev_set_drvdata() in your probe.
You have can find an example in drivers/rtc/rtc-ds1343.c but it is using an spi_driver.

Getting ENOTTY on ioctl for a Linux Kernel Module

I have the following chardev defined:
.h
#define MAJOR_NUM 245
#define MINOR_NUM 0
#define IOCTL_MY_DEV1 _IOW(MAJOR_NUM, 0, unsigned long)
#define IOCTL_MY_DEV2 _IOW(MAJOR_NUM, 1, unsigned long)
#define IOCTL_MY_DEV3 _IOW(MAJOR_NUM, 2, unsigned long)
module .c
static long device_ioctl(
struct file* file,
unsigned int ioctl_num,
unsigned long ioctl_param)
{
...
}
static int device_open(struct inode* inode, struct file* file)
{
...
}
static int device_release(struct inode* inode, struct file* file)
{
...
}
struct file_operations Fops = {
.open=device_open,
.unlocked_ioctl= device_ioctl,
.release=device_release
};
static int __init my_dev_init(void)
{
register_chrdev(MAJOR_NUM, "MY_DEV", &Fops);
...
}
module_init(my_dev_init);
My user code
ioctl(fd, IOCTL_MY_DEV1, 1);
Always fails with same error: ENOTTY
Inappropriate ioctl for device
I've seen similar questions:
i.e
Linux kernel module - IOCTL usage returns ENOTTY
Linux Kernel Module/IOCTL: inappropriate ioctl for device
But their solutions didn't work for me
ENOTTY is issued by the kernel when your device driver has not registered a ioctl function to be called. I'm afraid your function is not well registered, probably because you have registered it in the .unlocked_ioctl field of the struct file_operations structure.
Probably you'll get a different result if you register it in the locked version of the function. The most probable cause is that the inode is locked for the ioctl call (as it should be, to avoid race conditions with simultaneous read or write operations to the same device)
Sorry, I have no access to the linux source tree for the proper name of the field to use, but for sure you'll be able to find it yourself.
NOTE
I observe that you have used macro _IOW, using the major number as the unique identifier. This is probably not what you want. First parameter for _IOW tries to ensure that ioctl calls get unique identifiers. There's no general way to acquire such identifiers, as this is an interface contract you create between application code and kernel code. So using the major number is bad practice, for two reasons:
Several devices (in linux, at least) can share the same major number (minor allocation in linux kernel allows this) making it possible for a clash between devices' ioctls.
In case you change the major number (you configure a kernel where that number is already allocated) you have to recompile all your user level software to cope with the new device ioctl ids (all of them change if you do this)
_IOW is a macro built a long time ago (long ago from the birth of linux kernel) that tried to solve this problem, by allowing you to select a different character for each driver (but not dependant of other kernel parameters, for the reasons pointed above) for a device having ioctl calls not clashing with another device driver's. The probability of such a clash is low, but when it happens you can lead to an incorrect machine state (you have issued a valid, working ioctl call to the wrong device)
Ancient unix (and early linux) kernels used different chars to build these calls, so, for example, tty driver used 'T' as parameter for the _IO* macros, scsi disks used 'S', etc.
I suggest you to select a random number (not appearing elsewhere in the linux kernel listings) and then use it in all your devices (probably there will be less drivers you write than drivers in the kernel) and select a different ioctl id for each ioctl call. Maintaining a local ioctl file with the registered ioctls this way is far better than trying to guess a value that works always.
Also, a look at the definition of the _IO* macros should be very illustrative :)

Linux Kernel 3.13: How to list gendisk's?

I'm reading the online book about Linux Kernel drivers, which looks very obsolete to me. For example, the Linux Cross Reference can't find a variable gendisk_head (in kernel 3.13), which is supposed to point to a list of gendisk structures, available inside the kernel.
How can I list all the currently allocated gendisk structures from inside the kernel 3.13?
Take a look at the following code:
void __init printk_all_partitions(void)
{
struct class_dev_iter iter;
struct device *dev;
class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
while ((dev = class_dev_iter_next(&iter))) {
struct gendisk *disk = dev_to_disk(dev);

How to read VFS attributes in Linux

I have some question.
I try to read some VFS attributes, for example s_magic value in struct super_block.
but I cant read s_magic.
This is my code.
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<linux/fs.h>
int main()
{
int fd;
char boot[1024];
struct super_block sb;
fd = open("/dev/fd", O_RDONLY);
read(fd, boot, 1024);
read(fd, &sb, sizeof(struct super_block);
printf("%x\n", sb.s_magic);
close(fd);
return 0;
}
so, This code does't work with some error.
In this error, storage size of ‘sb’ isn’t known and invalid application of ‘sizeof’ to incomplete type ‘struct super_block’
Thank you.
That's because your linux/fs.h does not contain super_block declaration. That's because you want to include linux/fs.h from Linux kernel but actually include linux/fs.h from Linux userspace. Supply -I <include path> option to gcc like this
gcc -I /usr/src/kernels/$(uname -r)/include
BUT!
You will get a million of errors because you can't just include kernel headers in your userspace program - you don't have all type and struct definitions.
The kernel headers are not written with user space in mind, and they
can change at any time. The proper way for user-space applications to
interface with the kernel is by way of the C library, which provides
its own structures and, when necessary, translates them into whatever
the current kernel expects. This separation helps to keep user-space
programs from breaking when the kernel changes.
(source http://lwn.net/Articles/113349/)
So you have to revise your code.
P.S. I've given you and explanation why your code is not working, but I don't know how you can read super_block in userspace. You better ask another question regarding filesystem superblock API.

Using <linux/types.h> in user programs, or <stdint.h> in driver module code...does it matter?

I'm developing a device driver module and associated user libraries to handle the ioctl() calls. The library takes the pertinent info and puts it into a struct, which gets passed into the driver module and unpacked there and then dealt with (I'm omitting a lot of steps, but that's the overall idea).
Some of the data being passed through the struct via the ioctl() is uint32_t type. I've discovered that that type is defined in <stdint.h> AND <linux/types.h>. So far I've been using <linux/types.h> to define that value, including down in the user libraries. But I understand it is bad form to use <linux/*.h> libraries in user space, so if I remove those and use <stdint.h> instead, then when my driver module includes the struct definition, it will have to be including <stdint.h> also.
It seems to me that the point of <linux/types.h> is to define types in kernel files, so I'm not sure if that means using <stdint.h> is bad idea there. I also found that when trying to compile my driver module with <stdint.h>, I get compilation errors about redefinitions that won't go away, even if I replace all instances of <linux/types.h> with <stdint.h> (and put it on the top of the include order).
Is it a bad idea to use linux/*.h includes in user-space code?
Is it a bad idea to use <stdint.h> in kernel-space code?
If the answers to both of those is yes, then how do I handle the situation where a structure containing uint32_t is shared by both the user library and the driver module?
Is it a bad idea to use linux/*.h includes in user-space code?
Yes, usually. The typical situation is that you should be using the C-library headers (in this case, stdint.h and friends), and interface with the C library though those user-space types, and let the library handle talking with the kernel through kernel types.
You're not in a typical situation though. In your case, you're writing the driver library. So you should be presenting an interface to userspace using stdint.h, but using the linux/*.h headers when you interface to your kernel driver.
So the answer is no, in your case.
Is it a bad idea to use stdint.h in kernel-space code?
Most definitely yes.
See also: http://lwn.net/Articles/113349/
Fixed length integers in the Linux kernel
The Linux kernel already has fixed length integers which might interest you. In v4.9 under include/asm-generic/int-ll64.h:
typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
LDD3 has a chapter about data sizes as well: https://static.lwn.net/images/pdf/LDD3/ch11.pdf
LDD3 mentions there that the best printk strategy is to cast to just cast to the largest integer possible with correct signedness: %lld or %llu. %ju appears unavailable under the printk formatting centerpiece lib/linux/vsprintf.c.

Resources