I am trying to compile an external linux driver with the the line below within an existing platform using many dependencies (such as libraries):
obj-m += mydriver.o
KDIR ?= $(OUT_DIR)
default:
$(MAKE) -C $(KDIR) M=$$PWD
clean:
$(MAKE) -C $(KDIR) M=$$PWD clean
modules:
$(MAKE) -C $(KDIR) M=$$PWD modules
I have noticed that this invokes the kernel Makefile with creates object files and does the link in order to prepare a "module".ko loadable with linux. But what if, I have to use a specific library (eg. my_library.a): how can I prevent the Linux makefile to take into account this extra library when linking all the object files
Appendice:
My_library.a is a c++ source code contains functions that access to FPGA registers in order to report some useful data. Then my_driver (since it is a C code source , I had to create an C- interface from my_library.a ) will prepare basic system calls accessible from a user-space application. Bottom of line, my_driver reads from FPGA with 8khz, thanks to my_library.a via a C-interface and make data readable for user-space APP.
Cheers,
sahbi
Most probably, you cannot use an application-level external library libmy.a or my_library.a in any kernel module (or kernel code). Such libraries are generally built above the C standard library (e.g. because they use <stdio.h> thru fprintf or <stdlib.h> thru malloc), which does not exist for kernel code.
Conceptually kernel modules and kernel code is freestanding (i.e. not above the C standard library).
Notice that the ABI & calling conventions might be different in kernel code and in application code. And certainly, some standard functions (like malloc, printf, snprintf ....) might not exist inside the kernel. BTW kernel code is not allowed to use floating point, etc...
Of course, you could link your own kernel library (out of your own kernel object files), but that is often not worthwhile.
(an improbable exception could be some external library which do not use any standard C function and do not compute with floating point, but that does not happen in pracice)
At last, the conventional wisdom is to avoid needing lot of kernel code. So you should consider having some helper user-mode process. See netlink(7).
You probably should redesign your driver to avoid needing any external library. Since you read the FPGA at only 8KHz, that part of your code could sit in user-land above existing system calls.
Notice that kernel code cannot be written in C++
Related
We use Linux system calls like fork(), pthread(), signal() and so on in C or C++ programs and compile the program to generate executable file (a.out). Now my doubt is whether the file a.out contain the object code of all linux system calls used, or whether the executable contain only the calls to system functions and the system call functions are linked during runtime? Suppose if I move my a.out file to some other Linux operating system which implements system calls in different syntax and try to compile it there will it work?
My doubt is whether system call function definitions part of a.out file?
User space binaries don't contain implementations of system calls. That would mean that any user could inject any code into kernel and take over system.
Instead they need to switch to kernel mode, by using processor interrupt or special instruction. Then processor can execute system call implementation from the kernel.
User space library, such as libc, is usually used, which provides stubs, which convert arguments of a syscall to a proper protocol and trigger jump to kernel mode. It is usually linked dynamically, so these stubs also don't appear in executable file.
When I was trying to compile squid by hand on a RHEL 5.5 server, run configure and got
configure: WARNING: Eep! Cannot find epoll, kqueue, /dev/poll, poll or select!
configure: WARNING: Will try select and hope for the best.
configure: Using select for the IO loop.
Looks like the kernel is not configured with CONFIG_EPOLL. So I tried to compile this example epoll program to check whether it works.
On my gentoo box (which CONFIG_EPOLL is enabled.), it's compiled without any problem.
On the server, I got
/tmp/cc8PhJh0.o: In function 'main':
epoll-exmaple.c:(.text+0x262): undefined reference to 'epoll_create1'
collect2: ld returned 1 exit status
We all know for c program compiler looks for the definitions in *.h files and linker links them with *.so files.
My questions is, epoll_create1 is a system call to kernel. Which file exactly does linker search to locate the implementation to that system call?
Thanks.
It looks in the system C library (normally; a small handful of system calls are in other special libraries like librt). The C library provides a C API for userspace programs that handles making the system call for you. Sometimes this can be a very thin wrapper around the system call that just takes care of setting up and returning the arguments, but more frequently it has various glue that you don't want to have to worry about, such as differences in data sizes between userspace and the kernel, differences in implementation for the different architectures, backward or forward compatibility for changes in the kernel system call API, and so forth.
% readelf -s /lib/i386-linux-gnu/libc.so.6 | grep epoll_create1
1837: 000d5280 52 FUNC GLOBAL DEFAULT 12 epoll_create1##GLIBC_2.9
If you look at the C library as above, you can see the C function that the linker is linking code against.
I built linux kernel module with SSP support for mips architecture. I added -fstack-protector-all to compilation flags. But after loading this module I've got undefined references to __stack_chk_guard and __stack_chk_fail. But I added libssp.so to linker. It looks like I should export those symbols in kernel something like this:
EXPORT_SYMBOL(__stack_chk_guard);
Because my kernel is old and didn't contain them yet. But unfortunately I should use this version.
My question is: why user space can use this symbols from toolchain library, but kernel space don't ?
I think, I missed some linux kernel essentials.
You can't link the kernel to shared libraries. If you have a static library of libssp, it MAY work - but it would require that the library isn't calling something else that would cause problems in the kernel.
In general, stack-checking isn't something that you should be doing on the kernel - I'm pretty sure it serves no particularly good purpose [I'm also pretty sure that the kernel uses a "guard page" for each kernel stack].
You cannot use shared libraries anywhere in kernel space (including as part of kernel modules).
You could think of kernel modules themselves as an equivalent of shared libraries in kernel space but with lot of differences.
Kernel modules can depend on exported symbols from other kernel modules.
My question is: why user space can use this symbols from toolchain
library, but kernel space don't ?
Nothing in kernel space has access to the libc C library. Kernel has its own set of builtin standard string manipulation functions, etc. that you could use instead. The toolchain libraries are built on top of libc.
+1 on Mats's answer. You could use a static library as long as it does not depend on standard C libraries like libc
On a freshly installed Ubuntu , i found kernel headers in both /usr/include/linux , and /usr/src/kernel-version-headers/include/linux
Are they mutually the same ?
They are very different; the /usr/include/linux headers are the headers that were used when compiling the system's standard C library. They are owned by the C library packaging, and updated in lockstep with the standard C library. They exist to provide the userland interface to the kernel, as understood and "brokered"1 by the C library.
The /usr/src/linux-headers-$(uname -r)/include/linux headers are used via the /lib/modules/$(uname -r)/build symbolic links. They are owned by the kernel headers packages and updated in lockstep with the kernel. These are a subset of the kernel headers and enough of the Kbuild system required to build out-of-tree kernel modules. These files represent the kernel internals -- modules must build against these if they are to properly understand in-memory objects. See the kernel's Documentation/kbuild/modules.txt file for some details.
1: "Mediated" was my first word choice, but it implies some sort of access controls, which isn't the case. "Brokered" implies a third-party process, but that is also not the case. Consider: when a C program calls _exit(), it is actually calling the Standard C library's _exit() wrapper, which calls the exit(2) system call. The select(2) interface has an upper limit on the number of file descriptors that can be tracked, and that limit is compiled into the standard C library. Even if the kernel's interface were extended, the C library would also need to be recompiled.
Is it possible to compile a linux kernel(2.6) module that includes functionality defined by non-kernel includes?
For example:
kernelmodule.h
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h> // printk()
// ...
#include <openssl/sha.h>
// ...
Makefile
obj-m := kernelmodule.o
all:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` clean
$(RM) Module.markers modules.order
The kernel module I have written and are trying to compile contains functionality found in a number of openssl include files.
The standard makefile presented above doesn't allow includes outside of the linux headers. Is it possible to include this functionality, and if so, could you please point me in the right direction.
Thanks,
Mike
The kernel cannot use userspace code and must stand alone (i.e. be completely self contained, no libraries), therefore it does not pick up standard headers.
It is not clear what benefit trying to pick up userspace headers is. If there are things in there that it would be valid to use (constants, some macros perhaps provided they don't call any userspace functions), then it may be better to duplicate them and include only the kernel-compatible parts that you need.
It is not possible to link the kernel with libraries designed for userspace use - even if they don't make any OS calls - because the linking environment in the kernel cannot pick them up.
Instead, recompile any functions to be used in the kernel (assuming they don't make any OS or library calls - e.g. malloc - in which case they'll need to be modified anyway). Incorporate them into your own library to be used in your kernel modules.
Recent versions of linux contain cryptographic functions anyway, including various SHA hashes - perhaps you can use one of those instead.
Another idea would be to stop trying to do crypto in kernel-space and move the code to userspace. Userspace code is easier to write / debug / maintain etc.
I have taken bits of userspace code that I've written and converted it to work in kernel space (i.e. using kmalloc(), etc), it's not that difficult. However, you are confined to the kernel's understanding of C, not userspace, which differs slightly .. especially with various standard int types.
Just linking against user space DSO's is not possible — the Linux kernel is monolithic, completely self contained. It does not use userspace libc, libraries or other bits as others have noted.
9/10 times, you will find what you need somewhere in the kernel. It's very likely that someone else ran into the same need you have and wrote some static functions in some module to do what you want .. just grab those and re-use them.
In the case of crypto, as others have said, just use what's in the kernel. One thing to note, you'll need them to be enabled in kconfig which may or may not happen depending on what the user selects when building it. So, watch out for dependencies and be explicit, you may have to hack a few entries in kconfig that also select the crypto API you want when your module is selected. Doing that can be a bit of a pain when building out of tree.
So on the one hand we have "just copy and rename stuff while adding overall bloat", on the other you have "tell people they must have the full kernel source". It's one of the quirks that come with a monolithic kernel.
With a Microkernel, almost everything runs in userspace, no worries linking against a DSO for some driver ... it's a non issue. Please don't take that statement as a cue to re-start kernel design philosophy in comments, that's not in the scope of this question.