A linux kernel newbie question.
the man pages of mmap state that ".. otherwise, it shall return a value of MAP_FAILED and set errno to indicate the error... "
I have looked through the kernel code for mmap under /usr/src/linux/mm/mmap.c but I could not find a place where mmap returns MAP_FAILED.
Can anyone point me as to where can I find the same.
Thanks
You won't find MAP_FAILED in the kernel; instead, it's defined in userspace and used by mmap, the userspace function that wraps the system call. See the glibc source for mmap.
Related
I'm reading the gpiolib.c code in the linux kernel to understand how the GPIO driver works. But I didn't find any definition of "trace_gpio_value" function.
trace_gpio_value(desc_to_gpio(desc), 0, value);
Anybody can help me about definition of trace_gpio_value?
trace_gpio_value() and generally trace_*() are used by kernel ftrace static tracing utility to monitor some internals such as GPIO or networking (used for debugging and other purposes). These static tracing points cause collected data to be stored in a kernel buffer which you can see it's internals from tracing virtual file system mounted at /sys/kernel/tracing if Kconfig option CONFIG_FTRACE=y. So, in a nutshell these trace points will act as a hook to call other tracing functions that you provide.
About the actual definition and how they work you must declare your tracing point using DECLARE_TRACE() in your header file. In your case check include/trace/events/gpio.h where you specify your tracing function and how it will work:
#include <linux/tracepoint.h>
# note the NAME (first_parameter)
TRACE_EVENT(gpio_value,
...<SNIP...>
);
NOTE: TRACE_EVENT() is a macro that gets expanded to DECLARE_TRACE().
Then in your C code file you will add trace_gpio_value() whenever you want to trace and get the gpio_value() being called or another functions for another purposes.
I am passing pointer to below structure through ioctl.
typedef struct myparam_t {
int i;
char *myname;
}myparam;
I allocate memory for myname in the user space before passing the argument.
In the ioctl implementation at kernel space I use copy_from_user() to copy the argument in kspace variable (say kval). call is like copy_from_user(kval,uval,sizeof(myparam)); kval & uval are of myparam * type.
Now in ioctl function I have check like -
if (uval->myname != NULL) {
}
I thought this will result in to kernel crash or panic due to page fault.
However I see different behaviour with different version of kernel.
With 4.1.21 kernel I see no issue with NULL check, But with 4.10.17 kernel I see a page fault that results in to kernel panic.
My question is what might make NULL check working in kernel 4.1.21 ?
Is there a way I can make same code working for 4.10.17 as well ?
Note that I am facing this issue as part of kernel migration. We are trying to migrate from version 4.1.21 to 4.10.17. There may be many instance of such usage in our code base. Hence, if possible, I'd prefer to put a patch in kernel to fix the issue, rather than fixing all such instance.
Thanks
Dipak.
When a system call is invoked from 64-bit userspace to 64-bit kernel, syscall table is accessed from arch/x86/kernel/entry_64.S, from the system_call assembly entry point. How can I get the virtual/physical address of this "system_call()" routine?
In other words, I want to know the address of entry point used by all system calls. I tried looking at kallsyms file but couldn't find it there. Perhaps, it has another name in kallsyms?
Reference: https://lwn.net/Articles/604287/
What do you need this for? Are you sure you were inspecting kallsyms of the same kernel which was used in the article?
Figuring out what the func got renamed to is left as an exercise for the reader.
I know that you can't use malloc inside a kernel module because all functions used in the kernel must be defined in the kernel, but how exactly does the kernel achieve this lock-down?
It's not so much that it's locked down. It's just that your kernel module has no idea where malloc() is. The malloc() function is part of the C standard library, which is loaded alongside programs in userspace. When a userland program is executed, the linker will load the shared libraries needed by the program and figure out where the needed functions are. SO it will load libc at an address, and malloc() will be at some offset of that. So when your program goes to call malloc() it actually calls into libc.
Your kernel module isn't linked against libc or any other userspace components. It's linked against the kernel, which doesn't include malloc. Your kernel driver can't depend on the address of anything in userspace, because it may have to run in the context of any userspace program or even in no context, like in an interrupt. So the code for malloc() may not even be in memory anywhere when your module runs. Now if you knew that you were running in the context of a process that had libc loaded, and knew the address that malloc() was located at, you could potentially call that address by storing it in a function pointer. Bad things would probably happen though, possibly including a kernel panic. You don't want to cross userspace and kernelspace boundaries except through sane, well defined interfaces.
When you write a module for the kernel you just don't have this functions in your header files. And you don't have it in the files you are linking with.
Also the malloc's implementation is a procedure calling system calls. System calls moves you to hypervisor and calls the kernel's code. There is no point doing it while in hypervisor mode.
You can see it here in more details.
Recently I was looking through the kernel at kobjects and sysfs.
I know/understand the following..
All kernel objects use addresses > 0x80000000
kobjects should be no exception to this rule
The sysfs is nothing but a hierarchy of kobjects (maybe includes ksets and other k* stuff..not sure)
Given this information, I'm not sure I understand exactly what happens when I run echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
I can see that the cpufreq module has a function called store_scaling_governor which handles writes to this 'file'..but how does usermode transcend into kernelmode with this simple echo?
When you execute command echo ondemand >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor, your shell calls write system call, then kernel dispatch it for corresponding handler.
The cpufreq setups struct kobj_type ktype_cpufreq with sysfs_ops. Then cpufreq register it in cpufreq_add_dev_interface(). After that, kernel can get corresponding handler to execute on write syscall.
I can tell you one implementation which I have used for accessing kernel space variables from sysfs (user-space in shell prompt).Basically each set of variables which are exposed to user-space in sys file system appear as a separate file under /sys/.Now when you issue an echo value > /sys/file-path in shell prompt (user-space).When you do so the respective method which gets called in kernel space in .store method.Additionally when you issue cat /sys/file-path the respective method which gets called is .show in kernel.You can see more information about here: http://lwn.net/Articles/31220/