How to use systemcalls in linux modules - linux

I attempted to use systemcalls such as sys_sendto when programming a kernel module. But the compiler warned me that the symbol 'sys_sendto' is undefined. I'm sure I have inculded the header file syscalls.h, so please help me and thank you. P.S: My linux version is 2.6.32

For a module to link to a symbol in the kernel like sys_sendto(), it has to be exported by the kernel. Not all system calls are exported. See here

http://www.ibm.com/developerworks/linux/library/l-system-calls/
Here's a whole explanation on writing them and using them. They're not used by direct method calls because they have to be executed in kernel mode. The processor loads the syscall number into a register and then issues a hardware interrupt which the kernel processes and handles to execute your system call.

Related

How to port a linux driver , which is compiled in 2.6 kernel ,without compiling in other new version of kernel

Thanks to every one,
This is the question asked in one of the interview i faced.
I have a Linux device driver which was compiled in Linux kernel version 2.6.I would like to port the same driver in a Linux PC which has kernel 3.X without compiling in new versions.
Is it possible ? If it is possible please let me know how. If it is not possible please let me know why not ?
Thanks & Regards
Siva
No you cannot port module which is compiled for one version to other version.
The reason is as follows
Modules are strongly tied to the data structures and function prototypes defined in a particular kernel version;
the interface seen by a module can change significantly from one kernel version to
the next. This is especially true of development kernels, of course
The kernel does not just assume that a given module has been built against the
proper kernel version. One of the steps in the build process is to link your module
against a file (called vermagic.o) from the current kernel tree; this object contains a
fair amount of information about the kernel the module was built for, including the
target kernel version, compiler version, and the settings of a number of important
configuration variables. When an attempt is made to load a module, this information
can be tested for compatibility with the running kernel. If things don’t match,
the module is not loaded; instead, you see something like:
# insmod hello.ko
Error inserting './hello.ko': -1 Invalid module format
A look in the system log file (/var/log/messages or whatever your system is configured
to use) will reveal the specific problem that caused the module to fail to load.
Kernel interfaces often change between releases. If you are writing a module that is
intended to work with multiple versions of the kernel (especially if it must work
across major releases), you likely have to make use of macros and #ifdef constructs
to make your code build properly.
now it's not possible:
usually, a "driver" is a binary kernel-module
porting will involve code-changes to the kernel module. if you change the code, you need to compile it, in order to get a binary.
since kernel modules run in kernel space, it is crucial that they are robust. since parts of the kernel-API change every now and then, trying to use a module compiled for kernel-X with another kernel-Y, might either not load because of missing symbols (if you are lucky) or lead to a kernel panic because semantics have changed.
btw, all this is not really related to 2.6.x vs 3.y, but holds true for any kernel version
but then: of course in theory it is possible to "write" a kernel-module as binary code in your favourite hex-editor, without resorting to compilers and such. this would allow you to "port" a driver from one kernel to another without recompilation. i guess this is not for humans though...

Loadable kernel module trouble with sleep() function call in RedHat

I am facing an issue in trying to load an LKM into the RedHat kernel using insmod, but it returns me the following error:-
Insmod –f tmdq.o
tmdq.o: unresolved symbol sleep
Why should sleep() system call from within the LKM cause an issue? I wish to check if there is some other name given to sleep() in the Red Hat Linux 3.2.2-5, Linux version 2.4.20-8.
Also, is there a way to browse the source code of RedHat online, without having to download it?
Thanks.
First, sleep() is not as system call, it is implemented in libc by using sys_nanosleep syscall.
So there is no sleep in kernel, use msleep, mdelay or usleep_range (include/linux/delay.h) or maybe one of wait_event_ functions (include/linux/wait.h)
Definitions of msleep and other variants are not included in the kernel 2.4.20. One will have to implement it on his own using schedule_timeout() function of the kernel.
Additionally, this is where one can browse kernel code: lxr.linux.no

what methods do you take when your linux kernel programs are wrong?

I did not find a good method when I write and test a linux kernel programs such as multiple kernel-level threads or other general kernel modules, what methods do you take? thanks in advance!
printk, printk and more printk.
use dmesg to view. crash the kernel sometimes deliberately to get the crashinfo, then you can decode the crashinfo
dumptrace(), dumpstack() will print the stacktrace on the dmesg.
As a last option, kgdb. but this requires a connection to another system and is a pain always to get it work.

Linux how to debug OS freeze issue

I am working on a kernel module and a user-space application to test that module.
The problem is that during testing my system hangs/freeze.
I have placed lots of debug prints in the code.
The last message that is printed is just before linux select call in my user-space application. Does select somehow freeze the system?
So, How can i debug that where is problem? whether the problem is on user-space application or kernel module?
As n.m mentioned, your userspace program can't freeze Linux, so its an error in your kernel module. The best way to debug this is to use a kernel debugger, and figure out what your module is doing wrong.
Common errors are uninitialized pointers that your module passes to the kernel or locking issues, so take a close look at those.
A userspace program cannot, by definition, freeze Linux. There's a bug in the kernel.

Writing to a x86 MSR register from userland

I have an embedded system running Linux where I need to write to a specific MSR register at boot time, in order to fix a hardware issue.
Writing a kernel module is an obvious option, however there are several kernel versions around (all of them 2.6.xx) and the insmod/modprobe utils in the system do not have support for the -f flag. Thus I would need to compile and distribute a bunch of versions of the module, even when they are not using any kernel API. I would like to avoid this if possible.
Are there any options I may be overlooking?
Thanks!
msrtool reads MSRs via /dev/cpu/%d/msr; as documented in man 4 msr, the same path can be used to write them too.

Resources