linux kernel module char device - linux

i'm writing a char device in linux - xubuntu ,
and i'm wondering if i have to implement ioctl OR
maybe i can use the regular read write funcs??
thanks all,
Amit

The primary interface for a character device is the file functions, with ioctl serving extra, optional functionality.

If you're new to kernel module programming, you might want to check out the Linux Kernel Module Programming Guide.

The standard read/write functions are part of standard fops(file operations) structure in a character device driver model.If someone needs an additional functionality (which is user defined) and which is application dependent so you can go with ioctl() call.

Related

ioctl vs kernel modules in Linux

I know that kernel modules are used to write device drivers. You can add new system calls to the Linux kernel and use it to communicate with other devices.
I also read that ioctl is a system call used in linux to implement system calls which are not available in the kernel by default.
My question is, why wouldn't you just write a new kernel module for your device instead of using ioctl? why would ioctl b useful where kernel modules exist?
You will need to write a kernel driver in either case, but you can choose between adding a new syscall and adding a ioctl.
Let's say you want to add a feature to get the tuner settings for a video capturing device.
If you implement it as a syscall:
You can't just load a module, you need to change the kernel itself
Hundreds of drivers could each add dozens of syscalls each, kludging up the table with thousands of global functions that must be kept forever.
For the driver to have any reach, you will need to convince kernel maintainers that this burden is worthwhile.
You will need to upstream the definition into glibc, and people must upgrade before they can write programs for it
If you implement it as an ioctl:
You can build your module for an existing kernel and let users load it, without having to get kernel maintainers involved
All functions are simple per-driver constants in the applicable header file, where they can easily be added or removed
Everyone can start programming with it just by including the header
Since an ioctl is much easier, more flexible, and exactly meant for all these driver specific function calls, this is generally the preferred method.
I also read that ioctl is a system call used in linux to implement system calls which are not available in the kernel by default.
This is incorrect.
System calls are (for Linux) listed in syscalls(2) (there are hundreds of them between user space and kernel land) and ioctl(2) is one of them. Read also wikipage on ioctl and on Unix philosophy and Linux Assembler HowTo
In practice, ioctl is mostly used on device files, and used for things which are not a read(2) or a write(2) of bytes.
For example, a sound is made by writing bytes to /dev/audio, but to change the volume you'll use some ioctl. See also fcntl(2) playing a similar role.
Input/output could also happen (somehow indirectly ...) thru mmap(2) and related virtual address space system calls.
For much more, read Advanced Linux Programming and Operating Systems: Three Easy Pieces. Look into Osdev for more hints about coding your own OS.
A kernel module could implement new devices, or new ioctl, etc... See kernelnewbies for more. I tend to believe it might sometimes add a few new syscalls (but this was false in older linux kernels like 3.x ones)
Linux is mostly open source. Please download then look inside source code. See also Linux From Scratch.
IIRC, Linux kernel 1.0 did not have any kernel modules. But that was around 1995.

Transfer data from linux to fpga and inversely?

I have booted a ubuntu on a ZedBoard. I want to transfer data between fpga and linux. For example, I want to write or read a register from linux. What is best way for doing it? I have not any idea.
Thanx.
First of all, you need to specifically say what you want to do, for example. if you want to access the IO signals on the FPGA, you need to first add the GPIO module to your system, synthesize and implement it.
Then you use the Linux GPIO Driver to access the port as it is explained in this page:
Linux GPIO Driver
The GPIO driver fits in the Linux GPIO framework which is not a char
mode driver. Yet it does provide access to the GPIO by user space
through the sysfs filesystem. This allows each GPIO signal to be read
and written in similar manner to a char mode device. The interface is
somewhat documented in the kernel tree at Documentation/gpio.txt. The
following text is aimed to augment, not replace the existing
documentation.
For other, more complex interfaces you need to create your own driver or use one of the drivers that are available and modify it to fit your needs.

In linux, how can an user space program uses the kernel function? I really need some inspiration

I am a beginner of kernel programming. I just need some inspiration. I know I can write some functions in the kernel source, rebuild and reboot the kernel. The codes might be some hardware driver controlling the hardware. But how can our user space program use those functions?
I know through syscall the user space program can communicate with kernel space, and the loadable kernel module can also use the functions defined in kernel source code. But how can our user program achieve this?
PS: Now I am learning qemu-kvm. I know qemu is a user space program and kvm is kernel. I just want to figure out how qemu program uses kvm.
I know this is a very basic linux kernel programming problem but it confuses me for a long time. Can someone give me a hint? :>
You shouldn't insert a new syscall if you are programming a driver. New syscalls are usually a bad idea, you should have a very good reason to do it, and a hardware driver is not good one. You have to register your driver as char device, block device or network device. I recommend you the "Linux Device Driver" book (which is legally available on the Internet) to see examples of different type of drivers.
And about your question of how you can call a function in the kernel from userspace... there is no direct way to do it, you can't link userspace code with the kernel like you do with a library. First, you have to register your function as syscall and then call the syscall with the syscall() function.
Here is a good howto explaining it: http://www.tldp.org/HOWTO/html_single/Implement-Sys-Call-Linux-2.6-i386/

Linux Device Driver Registration procedure

I am a linux newbie, trying to understand Linux Device Model. I had been going through Linux 3.1.6 code base, particularly the driver part and found that
some of the drivers were using (for example i2c-bus device : linux-3.1.6/drivers/i2c/i2c-dev.c) *register_chrdev()* and
few others (for example pci bus : linux-3.1.6/drivers/pci/bus.c) were using *device_register()*.
My question is when to use register_chrdev (yes, I know its for a character device, but why not use device_register) and device_register ?
Does that depend on where does the driver developer wants his device/driver to be listed down, like devfs vs sysfs ? Or the interface exposed to the user space to access the device ?
One function registers a character device association (hooking up major:minors to your function), the other just creates an abstract device object (only), so to speak. The two are complementary. The device object is used for the generation of an event so that udev can, if there is also a cdev association registered, create a node in /dev. (Compare with, for example, drivers/char/misc.c.)
See when you register a device as a character device specifically then following thing happens:
Major Number is given in accordance. If you use any device depending on functionality whose registration is based on character device (like tty, input etc), then those will have their respective major number. Thats why its said that dont assign major number statically if not sure.
And
There are certain file operations which correspond to operations that could be performed on char devices only.
Do ask if any query.

How can I get edge events via GPIO on Linux without a busy-loop?

I'm working an a system with embedded Linux (Kernel 2.6.31).
It is a AT91SAM9G20 chip inside, and some of the Pins are forwarded to the outside.
Now I want to use them as GPIO Inputs.
I read the gpio.txt documentation about using the GPIOs via filesystem, and that works very well 'til here. I connected some switches to the gpio-pins and I can see the result in /sys/class/gpio/gpioX/value. But now I'd like to react on a change without busy-waiting in a loop. (i.e echo "Switch1 was pressed").
I guess I need interrupts here, but I couldn't find out how to use them without writing my own kernel driver. I'm relatively new to Linux and C (I normally program in Java), so I'd like to handle the Interrupts via sysfs too. But my problem is, that there is no "edge"-file in my GPIO directory (I guess because this is only since Kernel version 2.6.33+). Is that right? Instead of "edge" I've got a uevent file in there, which is not described in gpio.txt.
In the gpio.txt documentation there was a Standard Kernel Driver mentioned: "gpio_keys". Is it possible to use this for my problem?
I guess it would be better to work with this driver than allowing a userspace program to manipulate kernel tasks.
I found a lot of codesnippets for writing my own driver, but I wasn't even able to find out which of the 600 gpio.h files to include, and how to refer to the library (cross compiler couldn't find the gpio.h file).
Sorry for newbie questions, I hope you could give me some advices.
Thanks in advance
See this for an example on how to do that. Basically, the thing you're missing is the usage of the select or poll system calls.

Resources