Using real time kernel headers to compile userspace code vs default headers - linux

Per customer requirements, I installed CentOS 5.6 with the default kernel. With this kernel installed, the time.h file includes the #define CLOCK_MONOTONIC.
Now, a real-time kernel was installed along with the kernel-devel and our code would like to use CLOCK_MONOTONIC_RAW. It does exist as a part of the kernel's header files, but when I compile our code, it does not find it in the standard userspace includes.
My question is, what is the proper procedure to including/replacing the time.h found by default with the real-time kernel? From my research, it looks like symlinks are bad, so how should it be handled? What is the procedure or process? Upgrading to CentOS 6.0 or 5.7 is not an option per customer requirements. Thanks.

Well, userspace code uses userspace headers. Kernel modules use kernel headers (and that's why symlinks are bad, because you would be mixing userspace code with kernel headers).
To get the definition of CLOCK_MONOTONIC_RAW, you will have to update glibc — for CLOCK_ definitions, the "borderline" (they still count as userspace though!) headers in /usr/include/linux are not used.
With CentOS 5 default install, you are screwed, because both glibc (2.5) and the kernel (2.6.18) are too old; glibc-2.12 (commit glibc-2.12~111) and kernel-2.6.28 are the first to have MONOTONIC_RAW. That means it's got to be CentOS 6, or something else better.
You can try cheating your way in by using something like #ifndef CLOCK_MONOTONIC_RAW, #define CLOCK_MONOTONIC_RAW 4, #endif in your code, but that counts as unportable.

The definition of CLOCK_MONOTONIC_RAW is in /usr/local/include/linux/time.h on our Fedora 11 install but this header appears to be basically unusable . It doesn't declare clock_gettime or define clockid_t but it happily defines struct timerspec and struct itimerspec. The former is preceded by "#ifndef _STRUCT_TIMESPEC" so you can turn it off, but the latter is completely unprotected, which means that you can't include and in the same file without getting conflicting definitions.
There might be some contortion of #include directives that you could use to get this working using the headers in /usr/include, but I gave up and just copied the linux version to the source code directory for my project and then commented out the extra junk that I didn't need. So much for portability.

Related

asm vs asm-generic in linux headers -- are they same

In my linux header files folder on my Kali kernal 5.7.0 headers included in include directory /usr/src/linux-headers-5.7.0-kali1-common/include. Inside this folders I have header files contained in sub-folders like asm-generic,linux,uapi,acpi,crypto,etc.. But inside header files, i.e. inside linux/module.h there there is one header file reference included like
#include <asm/module.h> // top of linux/module.h
But Actually I don't have asm folder that got included with my header files when I installed them.
So one solution that came to mind is. Probably solution: Change the references from asm/* to asm-generic/* as in from asm/module.h to asm-generic/module.h inside linux/module.h and other files which I may use. I like to know is asm and asm-generic are same? meaning they contains same files and structure or is there any difference i can cause problem
If I correct the directory name in include reference than Does it make sense, or I will get into problems when I compile the module if I change headers sub directories names in include list of header files from asm to asm-generic? If I dont do this the header files will be missing
Short answer
They are not the same.
kernel developer might include asm-generic headers in a asm header while asm headers are the headers required for kernel modules.
You may get more info from following post
in linux kernel, asm or asm-generic?
Linux kernel headers' organization
linux module compilng missed folder asm
Take this question in another way.
It seems you're trying to make a kernel module.
To build a kernel module you need kernel-headers or compiled kernel source code. However I don't know kali linux, so I just provide generic suggestions here.
Where to get them
Some of distributions, like Ubuntu, have prebuilt linux-headers.
Eg: Ubuntu has it in /usr/src/linux-headers-$(uname -r)/include
Download it by sudo apt-get install linux-headers-$(uname -r)
It seems kali linux 2.0 might need more operations. Found this post might help.
Build it yourself
Checkout linux kernel code of your desired distro.
Set up kernel config with make menuconfig ( You might get stumbled here a while.. many packages might be required )
Compile kernel with make modules_prepare to compile essential Module.symvers for drivers. It take significant less time than compiling a full kernel.
I presume you already found a kernel module build example. If not, you may consult offical kernel module documentation. It helps a lot if you take a while to read first two chapters.
Or another example

Get kernel version | Linux kernel API [duplicate]

how can I obtain runtime information about which version of kernel is running from inside linux kernel module code (kernel mode)?
By convention, Linux kernel module loading mechanism doesn't allow loading modules that were not compiled against the running kernel, so the "running kernel" you are referring to is most likely is already known at kernel module compilation time.
For retrieving the version string constant, older versions require you to include <linux/version.h>, others <linux/utsrelease.h>, and newer ones <generated/utsrelease.h>. If you really want to get more information at run-time, then utsname() function from linux/utsname.h is the most standard run-time interface.
The implementation of the virtual /proc/version procfs node uses utsname()->release.
If you want to condition the code based on kernel version in compile time, you can use a preprocessor block such as:
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
...
#else
...
#endif
It allows you to compare against major/minor versions.
You can only safely build a module for any one kernel version at a time. This means that asking from a module at runtime is redundant.
You can find this out at build time, by looking at the value of UTS_RELEASE in recent kernels this is in <generated/utsrelease.h> amongst other ways of doing this.
Why can't I build a kernel module for any version?
Because the kernel module API is unstable by design as explained in the kernel tree at: Documentation/stable_api_nonsense.txt. The summary reads:
Executive Summary
-----------------
You think you want a stable kernel interface, but you really do not, and
you don't even know it. What you want is a stable running driver, and
you get that only if your driver is in the main kernel tree. You also
get lots of other good benefits if your driver is in the main kernel
tree, all of which has made Linux into such a strong, stable, and mature
operating system which is the reason you are using it in the first
place.
See also: How to build a Linux kernel module so that it is compatible with all kernel releases?
How to do it at compile time was asked at: Is there a macro definition to check the Linux kernel version?

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...

compiling linux kernel with non-gcc

Linux kernel is written for compiling with gcc and uses a lot of small and ugly gcc-hacks.
Which compilers can compile linux kernel except gcc?
The one, which can, is the Intel Compiler. What minimal version of it is needed for kernel compiling?
There also was a Tiny C compiler, but it was able to compile only reduced and specially edited version of the kernel.
Is there other compilers capable of building kernel?
An outdatet information: you need to patch the kernel in order to compile using the Intel CC
Download Linux kernel patch for Intel® Compiler
See also Is it possible to compile Linux kernel with something other than gcc for further links and information
On of the most recent sources :http://forums.fedoraforum.org/showthread.php?p=1328718
There is ongoing process of committing LLVMLinux patches into vanilla kernel (2013-2014).
The LLVMLinux is project by The Linux Foundation: http://llvm.linuxfoundation.org/ to enable vanilla kernel to be built with LLVM. Lot of patches are prepared by Behan Webster, who is LLVMLinux project lead.
There is LWN article about the project from May 2013
https://lwn.net/Articles/549203/ "LFCS: The LLVMLinux project"
Current status of LLVMLinux project is tracked at page http://llvm.linuxfoundation.org/index.php/Bugs#Linux_Kernel_Issues
Things (basically gcc-isms) already eliminated from kernel:
* Expicit Registers Variables (non-C99)
* VLAIS (non C99-compliant undocumented GCC feature "Variable length arrays in structs") like struct S { int array[N];} or even struct S { int array[N]; int array_usb_gadget[M]; } where N and M are non-constant function argument
* Nested Functions (Ada feature ported into C by GCC/Gnat developers; not allowed in C99)
* Some gcc/gas magic like special segments, or macro
Things to be done:
* Usage of __builtin_constant_p builtin to implement scary magic like BUILD_BUG_ON(!__builtin_constant_p(offset));
The good news about LLVMLinux are that after its patches kernel not only becomes buildable with LLVM+clang, but also easier to build by other non-GCC compilers, because the project kills much not C99 code like VLAIS, created by usb gadget author, by netfilter hackers, and by crypto subsystem hackers; also nested functions are killed.
In short, you cannot, because the kernel code was written to take advantage of the gcc's compiler semantics...and between the kernel and the compiled code, the relationship is a very strong one, i.e. must be compiled with gcc...Since gcc uses 'ELF' (Embedded Linking Format) object files, the kernel must be built using the object code format. Unless you can hack it up to work with another compiler - it may well compile but may not work, as the compilers under Windows produces PE code, there could be unexpected results, meaning the kernel may not boot at all!

Compile linux kernel (2.6) module including non kernel headers

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.

Resources