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 :)
Related
I have gone through the following topic and I still have some questions.
ioread32 followed by iowrite32 not giving same value
In the link, where can I get my base which is defined as 0xfed00000
in the post ?
what should I put for the second parameter in
void request_mem_region(unsigned long start, unsigned long len,char *name);
what should I put for the second parameter in
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
By having the Makefile and generating the kernel module, I should use the insmod and then dmesg to check if the code works as I expect, is this correct ?
In the case, should I add iounmap(virtual_base); before return 0; in the source ?
Thanks
In the link, where can I get my base which is defined as 0xfed00000 in the post ?
It's the base (physical) address of the peripheral's registers.
If the peripheral is a discrete chip on the board, then consult the board documentation.
If the peripheral is embedded in a SoC, then consult the memory map in the SoC datasheet.
what should I put for the second parameter in
void request_mem_region(unsigned long start, unsigned long len,char *name);
what should I put for the second parameter in
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
These two routines should be called with the same first and second parameters.
The length/size is the number of bytes the peripheral's register set occupies.
Sometimes the entire memory region to the next peripheral is specified.
By having the Makefile and generating the kernel module, I should use the insmod and then dmesg to check if the code works as I expect, is this correct ?
A judicious sprinkling of printk() statements is the tried & true method of testing a Linux kernel driver/module.
Unix has kdb.
In the case, should I add iounmap(virtual_base); before return 0; in the source ?
Do not copy that poorly written example of init code.
If ioremap() is performed in a driver's probe() (or other initialization) routine, then the iounmap() should be in the probe's error exit sequence and in the driver's remove() (or the complementary to init) routine.
There are numerous examples to study in the Linux kernel source. Use an online Linux cross reference such as http://lxr.free-electrons.com/source/
Note that almost all Linux drivers use iounmap() two or more times.
I want to know as to where IOCTL is defined. I want to flip the state of a GPIO pin from within the IOCTL function call. I am using Yocto linux.
The ioctl requests are defined per driver. For the new chardev GPIO this is defined in <linux/gpio.h>.
The logic these values are encoded is in <asm/ioctl.h>. Please note, that this is platform dependent (e.g. MIPS is different than x86 and x86_64).
If you are interested, here is the logic ported to rust: https://docs.rs/nix/0.11.0/src/nix/sys/ioctl/linux.rs.html
However in practice you shouldn't need to convert these request codes on your own. You would just include <linux/gpio.h> and then you can use the defined IOCTL request codes like GPIOHANDLE_GET_LINE_VALUES_IOCTL. Here are some example implementations: https://github.com/torvalds/linux/tree/master/tools/gpio
ioctl is a c-language kernel function declared in <sys/ioctl.h>. See the linux manual page.
Here's a copy of the upper portion:
NAME
ioctl - control device
SYNOPSIS
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
DESCRIPTION
The ioctl() function manipulates the underlying device parameters of
special files. In particular, many operating characteristics of
character special files (e.g., terminals) may be controlled with
ioctl() requests. The argument fd must be an open file descriptor.
The second argument is a device-dependent request code. The third
argument is an untyped pointer to memory. It's traditionally char
*argp (from the days before void * was valid C), and will be so named
for this discussion.
An ioctl() request has encoded in it whether the argument is an in
parameter or out parameter, and the size of the argument argp in
bytes. Macros and defines used in specifying an ioctl() request are
located in the file <sys/ioctl.h>.
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.
I have an embedded system I'm working with, and it currently uses the sysfs to control certain features.
However, there is function that we would like to speed up, if possible.
I discovered that this subsystem also supports and ioctl interface, but before rewriting the code, I decided to search to see which is a faster interface (on ucLinux) in general: sysfs or ioctl.
Does anybody understand both implementations well enough to give me a rough idea of the difference in overhead for each? I'm looking for generic info, such as "ioctl is faster because you've removed the file layer from the function calls". Or "they are roughly the same because sysfs has a very simple interface".
Update 10/24/2013:
The specific case I'm currently doing is as follows:
int fd = open("/sys/power/state",O_WRONLY);
write( fd, "standby", 7 );
close( fd );
In kernel/power/main.c, the code that handles this write looks like:
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
#ifdef CONFIG_SUSPEND
suspend_state_t state = PM_SUSPEND_STANDBY;
const char * const *s;
#endif
char *p;
int len;
int error = -EINVAL;
p = memchr(buf, '\n', n);
len = p ? p - buf : n;
/* First, check if we are requested to hibernate */
if (len == 7 && !strncmp(buf, "standby", len)) {
error = enter_standby();
goto Exit;
((( snip )))
Can this be sped up by moving to a custom ioctl() where the code to handle the ioctl call looks something like:
case SNAPSHOT_STANDBY:
if (!data->frozen) {
error = -EPERM;
break;
}
error = enter_standby();
break;
(so the ioctl() calls the same low-level function that the sysfs function did).
If by sysfs you mean the sysfs() library call, notice this in man 2 sysfs:
NOTES
This System-V derived system call is obsolete; don't use it. On systems with /proc, the same information can be obtained via
/proc/filesystems; use that interface instead.
I can't recall noticing stuff that had an ioctl() and a sysfs interface, but probably they exist. I'd use the proc or sys handle anyway, since that tends to be less cryptic and more flexible.
If by sysfs you mean accessing files in /sys, that's the preferred method.
I'm looking for generic info, such as "ioctl is faster because you've removed the file layer from the function calls".
Accessing procfs or sysfs files does not entail an I/O bottleneck because they are not real files -- they are kernel interfaces. So no, accessing this stuff through "the file layer" does not affect performance. This is a not uncommon misconception in linux systems programming, I think. Programmers can be squeamish about system calls that aren't well, system calls, and paranoid that opening a file will be somehow slower. Of course, file I/O in the ABI is just system calls anyway. What makes a normal (disk) file read slow is not the calls to open, read, write, whatever, it's the hardware bottleneck.
I always use low level descriptor based functions (open(), read()) instead of high level streams when doing this because at some point some experience led me to believe they were more reliable for this specifically (reading from /proc). I can't say whether that's definitively true.
So, the question was interesting, I built a couple of modules, one for ioctl and one for sysfs, the ioctl implementing only a 4 bytes copy_from_user and nothing more, and the sysfs having nothing in its write interface.
Then a couple of userspace test up to 1 million iterations, here the results:
time ./sysfs /sys/kernel/kobject_example/bar
real 0m0.427s
user 0m0.056s
sys 0m0.368s
time ./ioctl /run/temp
real 0m0.236s
user 0m0.060s
sys 0m0.172s
edit
I agree with #goldilocks answer, HW is the real bottleneck, in a Linux environment with a well written driver choosing ioctl or sysfs doesn't make a big difference, but if you are using uClinux probably in your HW even few cpu cycles can make a difference.
The test I've done is for Linux not uClinux and it never wanted to be an absolute reference profiling the two interfaces, my point is that you can write a book about how fast is one or another but only testing will let you know, took me few minutes to setup the thing.
I have an powerpc board with 3.2 kernel running on it. Accessing gpio with sysfs works as expected e.g.
> echo 242 > /sys/class/gpio/export
> cat /sys/class/gpio/gpio242/value
> 1
Is there no API to direct access gpio pins from user space? Must I deal with the text based sysfs interface?
I seach for something like:
gpio_set(int no, int val);
Thanks
Klaus
GPIO access through sysfs has been deprecated since Linux 4.8.
The new way for user space access is through libgpiod, which includes a library to link with (obviously), as well as some tools which can be run from the command line (for scripting convenience). Notably, GPIO lines are referenced with the line name string rather than an integer identifier, like with sysfs. E.g.
gpioset $(gpiofind "USR-LED-2")=1
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/README
Edit: sysfs direct access for GPIOs is deprecated, new way is programmatic through libgpiod
sysfs is the lowest level at which you will be able to manipulate GPIO in recent kernels. It can be a bit tedious but it offers several advantages over the old style API:
No ugly ioctl
Can be scripted very easily (think startup scripts)
For inputs, the "value" file can easily be poll-ed for rising/falling/both edges and it will be very reactive to hardware interrupts
I have no example code at the moment but when accessing them through C code, I often implemented a very simple wrapper manipulating file descriptors and having variations of the following interface:
int gpio_open(int number, int out); /* returns handle (fd) */
int gpio_close(int gpio);
int gpio_set(int gpio, int up);
int gpio_get(int gpio, int *up);
int gpio_poll(int gpio, int rising_edge, int timeout);
From then, the implementation is pretty straightforward.
Once you have the devices created in the vfs tree, you can open them like typical files assuming you have a driver written and have the correct major and minor numbers assigned in the makedev file that creates the gpio pins on the vfs tree.
Every GPIO is memory mapped as a register, so you can access to it through /dev/mem. See here. If you want to access directly to a GPIO you have to work at kernel space level