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

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

Related

Editing compiled kernel module for more compatibility

I want to edit compiled kernel module file (module.ko) to insert something like "MODULE_INFO(vermagic, "3.10.9-blabla");" because this module file does not load with insmod and i get the error "failed (Exec format error)", the module was made for 2.6.35-smp version, I'm new to linux.
You cannot edit a compiled module directly.
Whatever change you need to do, you have to edit the source file and then compile it again.
From version 2.6.35 to 3.10 quite a lot of things changed; most likely the module is not compatible at all and it will not work. So, even if you can change the vermagic in the binary file it will not work because it's incompatible.
In your case, as Hector said, you have to recompile the module against a different Linux version. This process will also highlight all the incompatibilities that you should fix too.
If you do not have the sources because it is not an open source module: complain with the vendor :)
Although you will not be able to edit your compiled module now, build your kernel with CONFIG_MODVERSIONS is not set from next time, for driver development. It will enable you to make any number of incremental changes to your driver and load it against the newly built kernel with CONFIG_MODVERSIONS is not set.
CONFIG_MODVERSIONS is a notion thought up to make people's lives easier. If your kernel is compiled with CONFIG_MODVERSIONS=y, it enables you
to only be able to load modules that were compiled specifically for
that kernel version. Whereas, if your kernel is built with CONFIG_MODVERSIONS is not set, it will enable your driver to load on any kernel where CONFIG_MODVERSIONS is not set. You can modify this field in the .config file of your linux-kernel directory.

How to build the elf interpreter (ld-linux.so.2/ld-2.17.so) as static library?

I apologize if my question is not precise because I don't have a lot
of Linux related experience. I'm currently building a Linux from
scratch (mostly following the guide at linuxfromscratch.org version
7.3). I ran into the following problem: when I build an executable it
gets a hardcoded path to something called ELF interpreter.
readelf -l program
shows something like
[Requesting program interpreter: /lib/ld-linux.so.2]
I traced this library ld-linux-so.2 to be part of glibc. I am not very
happy with this behaviour because it makes the binary very unportable
- if I change the location of /lib/ld-linux.so.2 the executable no
longer works and the only "fix" I found is to use the patchelf utility
from NixOS to change the hardcoded path to another hardcoded path. For
this reason I would like to link against a static version of the ld
library but such is not produced. And so this is my question, could
you please explain how could I build glibc so that it will produce a
static version of ld-linux.so.2 which I could later link to my
executables. I don't fully understand what this ld library does, but I
assume this is the part that loads other dynamic libraries (or at
least glibc.so). I would like to link my executables dynamically, but
I would like the dynamic linker itself to be statically built into
them, so they would not depend on hardcoded paths. Or alternatively I
would like to be able to set the path to the interpreter with
environment variable similar to LD_LIBRARY_PATH, maybe
LD_INTERPRETER_PATH. The goal is to be able to produce portable
binaries, that would run on any platform with the same ABI no matter
what the directory structure is.
Some background that may be relevant: I'm using Slackware 14 x86 to
build i686 compiler toolchain, so overall it is all x86 host and
target. I am using glibc 2.17 and gcc 4.7.x.
I would like to be able to set the path to the interpreter with environment variable similar to LD_LIBRARY_PATH, maybe LD_INTERPRETER_PATH.
This is simply not possible. Read carefully (and several times) the execve(2), elf(5) & ld.so(8) man pages and the Linux ABI & ELF specifications. And also the kernel code doing execve.
The ELF interpreter is responsible for dynamic linking. It has to be a file (technically a statically linked ELF shared library) at some fixed location in the file hierarchy (often /lib/ld.so.2 or /lib/ld-linux.so.2 or /lib64/ld-linux-x86-64.so.2)
The old a.out format from the 1990s had a builtin dynamic linker, partly implemented in old Linux 1.x kernel. It was much less flexible, and much less powerful.
The kernel enables, by such (in principle) arbitrary dynamic linker path, to have various dynamic linkers. But most systems have only one. This is a good way to parameterize the dynamic linker. If you want to try another one, install it in the file system and generate ELF executables mentioning that path.
With great pain and effort, you might make your own ld.so-like dynamic linker implementing your LD_INTERPRETER_PATH wish, but that linker still has to be an ELF shared library sitting at some fixed location in the file tree.
If you want a system not needing any files (at some predefined, and wired locations, like /lib/ld.so, /dev/null, /sbin/init ...), you'll need to build all its executable binaries statically. You may want (but current Linux distributions usually don't do that) to have a few statically linked executables (like /sbin/init, /bin/sash...) that will enable you to repair a system broken to the point of not having any dynamic linker.
BTW, the /sbin/init -or /bin/sh - path is wired inside the kernel itself. You may pass some argument to the kernel at boot load time -e.g. with GRUB- to overwrite the default. So even the kernel wants some files to be here!
As I commented, you might look into MUSL-Libc for an alternative Libc implementation (providing its own dynamic linker). Read also about VDSO and ASLR and initrd.
In practice, accept the fact that modern Linuxes and Unixes are expecting some non-empty file system ... Notice that dynamic linking and shared libraries are a huge progress (it was much more painful in the 1990s Linux kernels and distributions).
Alternatively, define your own binary format, then make a kernel module or a binfmt_misc entry to handle it.
BTW, most (or all) of Linux is free software, so you can improve it (but this will take months -or many years- of work to you). Please share your improvements by publishing them.
Read also Drepper's Hwo to Write Shared Libraries paper; and this question.
I ran into the same issue. In my case I want to bundle my application with a different GLIBC than comes system installed. Since ld-linux.so must match the GLIBC version I can't simply deploy my application with the according GLIBC. The problem is that I can't run my application on older installations that don't have the required GLIBC version.
The path to the loader interpreter can be modified with --dynamic-linker=/path/to/interp. However, this needs to be set at compile time and therefore would require my application to be installed in that location (or at least I would need to deploy the ld-linux.so that goes with my GLIBC in that location which goes against a simple xcopy deployment.
So what's needed is an $ORIGIN option equivalent to what the -rpath option can handle. That would allow for a fully dynamic deployment.
Given the lack of a dynamic interpreter path (at runtime) leaves two options:
a) Use patchelf to modify the path before the executable gets launched.
b) Invoke the ld-linux.so directly with the executable as an argument.
Both options are not as 'integrated' as a compiled $ORIGIN path in the executable itself.

Kernel source on precise-armhf v3.6.2-x3 on a BeagleBoard XM

I have a BeagleBoard XM on which I installed Ubuntu from rcn-ee. Now, I'm looking to install the 8192cu driver because I can't get WiFi to work with the kernel driver. However, the makefile for the driver needs a path to the kernel source, which I can't find.
I think the kernel is in /lib/modules/3.6.2-x3/kernel, but that doesn't seem to have the source. How/where can I get the source for this in order to install the driver?
Note: If I give
KSRC := /lib/modules/3.6.2-x3/
I get
No rule to make target 'modules'. Stop.
To build drivers you should only need the kernel headers. There is a thread on the beagleboard group that explains where to find the source and headers (note that it is fairly old, so you may need to adjust for your build).
This post also looks relevant

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

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.

Why would the ELF header of a shared library specify Linux as the OSABI?

All the standard shared libraries on my Linux system (Fedora 9) specify ELFOSABI_NONE (0) as their OSABI.
This is fine - however I've received a shared library from a supplier where the OSABI given in the ELF header is ELFOSABI_LINUX (3).
This doesn't sound like an unreasonable value for a shared library intended for a Linux system, however it is a different value to that of all my other libraries - and so when I try to open this library, with dlopen(), from one of my other libraries this fails with the error "ELF file OS ABI invalid".
I compiled up the FreeBSD utility brandelf.c and used it to change the OSABI type to 0 and now the library seems to play fine with everything else.
I'm just wondering - why do you think this library is marked as ELFOSABI_LINUX? I'm guessing maybe they cross compiled on another system and specified some gcc flag that caused this value to be set into the ELF header? I tried to achieve something similar but couldn't determine the appropriate gcc flag or flags.
I'd like to know what the likely cause is as this particular supplier wont do anything without a lot of hand holding and I'd like to be able to say "you're probably doing X but this means we have to modify your libraries after we take delivery of them".
Possibly the vendor is cross compiling on FreeBSD or using a very recent Fedora system where anything using STT_GNU_IFUNC will be marked as ELFOSABI_LINUX. If you are trying to use it on Linux there should be no problems with changing it to ELFOSABI_NONE like you have done.

Resources