What does this make command do? - linux

make -C $(KERNEL_DIR) SUBDIRS=pwd` modules
Can someone elaborate this?

The -C means "change to this directory before starting make." The SUBDIRS is a variable used by the Linux kernel make system. SUBDIRS=`pwd` means that the kernel makefiles should look in the current directory, because pwd means "print working directory." And modules means to make modules.
It probably uses the kernel make system to build an out-of-tree module. Out-of-tree means a kernel module that is not shipped with the kernel.
In fact, I seem to recall seeing this command used as part of the Nvidia binary module installer.

Related

Not able to compile C program which is including <linux/leds.h>

I am trying to compile my led wrapper function program file with including linux/leds.h
using including kernel space header files
gcc -I /usr/src/linux-headers-3.13.0-44-generic/include/ example.c
by compiling it flooded the console with errors in many headers file those are depended on leds.h. Can any one please help me to compile this C file which is using kernel space header files in user space.
Thanks in advance. :)
This won't work.
First of all, don't use kernel-mode headers in user-mode programs, except for the (processed?) ones provided for userspace after kernel compilation. Kernel-mode headers depend on the kernel build system to work.
I tried this, just for curiosity, although I did already knew why it won't work (tl;dr, I use the Ubuntu-patched 3.13.0-24 kernel):
$ cd /usr/src/linux-headers-3.13.0-24/
$ echo '#include <linux/leds.h>' | gcc -E -x c -o - - -Iinclude
The preprocessor claims that <asm/linkage.h> is missing, and, correct me if I'm wrong, that header is generated by the kernel build system.
If you want, you can solve this by creating a kernel module that uses <linux/leds.h> et al, then export a userspace API through the module (usually done through /proc or /sys) and use that API to implement your usermode code's logic.
Hope this helps!
Thanks KemyLand, You were right that we can not use kernel space header file in user space. But your approach couldn't work for me. firstly it asked for asm/linkage.h, i included the path of it explicitly but again compilation terminated on another header file and i did same. But at last i blocked on some errors in headers files, which were not expected as i didn't make any changes in those files. but finally i got the solution. basically we have to do Interfacing functions between kernel space and the hardware device. I had to generate make file for it. obj-m :=file_name.o and compiled it by following command make -C /usr/src/linux-headers-3.13.0-44-generic/ -C /usr/include/ M=pwd modules it generated 4 files file_name.mod.o , file_name.o, file_name.ko, file_name.mod.c. and then loaded the module as root by insmod file_name.ko. for checking the loaded module type command lsmod. I can also execute it by typing command insmod ./file_name.o or can remove by rmmod file_name

How to build kernel module without full kernel source tree?

I would like to build kernel module without kernel source tree.
Instead that, I specified the kernel header directory only.
This reference link tell me it should be workable :
build kernel module w/o source source tree
But some other reference links tell me should build module with full kernel source tree!
My question is :
1. Shall I build kernel module link with full kernel source tree ?
2. Is it necessary to do a full build under kernel source tree before build my single module ?
Not it's not necessary. You need a header files that contains function and types declarations. You also kernel tree with Makefiles and Kconfig but without sources. This kernel tree is needed by kbuild - kernel building system.
Absolutely not. You can build a single module without building whole kernel regardless of it's out-of-tree or in-tree module.
No to both questions. You're talking about out-of-tree (or "external") modules.
Here is a tutorial of Building External Modules.
And here is a simple sample of a Makefile.
obj-m += your-module.o
KDIR=/lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules

building /lib/modules/$(uname -r)/build while compiling a kernel

I am cross-compiling 3.4.0 kernel for an embedded device. Then I would like to install compat-wireless drivers which require /lib/modules/3.4/build directory and sub-files. Could anyone explain how can I build that directory so that when I do INSTALL_MOD_PATH=newmodules make modules_install it would load /lib/modules/$(uname -r)/build directory as well? I would appreciate for a clear explanation.
I am using debian distro. I know I can install the kernel headers by apt-get install linux-headers-$(uname -r), but I doubt it would be a good idea since the kernel sources might not be identical.
Typically /lib/modules/$(uname -r)/build is a soft-link to the directory where performed the build. So the way to do this is to simply do a
make modules_install INSTALL_MOD_PATH=/some/root/
in the build directory of the kernel where /some/root is where you want your cross compile pieces to end up. This will create a link to your kernel build path in /some/root/lib/modules/$(uname -r) ... verify that.
Now when you build the compat_wireless drivers specify the kernel build directory in the Makefile as /some/root using the KLIB_BUILD variable (read the Makefile)
make modules KLIB_BUILD=/some/root/lib/modules/$(uname -r)/build
this should do the trick for you.
EDIT A
In answer to your comment below:
Keep "newmodules" outside the kernel directory it's a bad idea to put it in the kernel directory. so mkdir newmodules somewhere like /home/foo or /tmp or something. This is one of the reasons your build link is screwed up
ALSO .../build is a soft link /to/kernel/build/location it will only copy over as a soft-link. You also need to copy over the actual kernel source / kernel build directory to your microSD, using the same relative location. For example,
Let's say your kernel source is in:
/usr/src/linux-3.5.0/
Your kernel build directory is:
/usr/src/linux-3.5.0-build/
Your newmodules (after following 1.) is in:
/tmp/newmodules/
So under /tmp/newmodules/ you see the modules installed in a tree like:
lib/modules/$(uname -r)/
when you do an ls -al in this directory, you'll see that build is a soft link to:
build -> /usr/src/linux-3.5.0-build/
Now let's say your microSD is mounted under /mnt/microSD
then you need to do the following
mkdir -p /mnt/microSD/usr/src
cp -a /usr/src/linux-3.5.0 /usr/src/linux-3.5.0-build /mnt/microSD/usr/src
cp -a /tmp/newmodules/lib /mnt/microSD/lib
Now you have all the content you need to bring over to your embedded environment. I take it you are doing the compat_wireless build on your target system rather than cross compiling it?
NOTE
If your kernel build is the same as the kernel source then just copy over the kernel source and ignore the linux-3.5.0-build in copy instructions above
This is old, but some people will need this information.
I have spent many hours to figure out where build folder comes from, and why it is just a link when I compile my own kernel. Finally figured it out;
Linux kernel usually just links the build and source folders to the source folder.
But!
Arch linux (probably some other distros too); has a manual script for deleting those links, and adding (filtered) files to build folder.
https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/linux
I've extracted that script to work standalone (in a kernel source tree) here: https://gist.github.com/furkanmustafa/9e73feb64b0b18942047fd7b7e2fd53e

missing modversions.h on linux

I have configured and built linux kernel 2.6.27 successfully, with module supported enabled. But when I am trying to build another program (kernel module) that needs include/linux/modversions.h, it cannot find the file.
my question is: besides enabling the module support in linux kernel config, is there anything else I need to do to generate/get the modversions.h?
Thanks.
Run a find /path/to/kernel -name modversions.h, you'll probably find one in a config dir and another on a linux dir, if so it was compiled with your kernel.
If that module was compiled then it can be installed with make modules_install, though that will install all the compiled modules, not their headers.
To tell gcc to search for the kernel source when compiling use the -I option -I/path/to/kernel.
You can also use the INCLUDE_DIRS var to tell gcc to include that dir, export INCLUDE_DIRS=$INCLUDE_DIRS:/path/to/kernel.

Driver/module cross compilation

I am trying to cross compile a driver for an arm based board. In the make file the search path for include files is that of the host machine's kernel i.e it points to the linux headers that come with ubuntu.
I also have the kernel source tree of target board present on the host system(i7/ubuntu).
My Question is that which include path is needed for cross compilation (native system's linux headers path or the path to the kernel source tree of board ?
Does same thing applies to all modules including drivers?
Here is a Makefile for an out of tree driver. The architecture, toolchain and kernel dir specified :
ifneq ($(KERNELRELEASE),)
# We were called by kbuild
obj-m += fpgacam.o
else # We were called from command line
KDIR := path/to/your/target/kernel
PWD := $(shell pwd)
CROSS=arm-none-linux-gnueabi-
default:
#echo ' Building Cam drivers for 2.6 kernel.'
#echo ' PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS) modules
install:
./do_install.sh *.ko
endif # End kbuild check
######################### Version independent targets ##########################
clean:
rm -f -r *.o *.ko .*cmd .tmp* core *.i
When make is called from the module directory, the command line path is taken, and make is redirected to the kernel directory build system using make -C. The kernel build system then the different variable passed to it to go back into the module directory with everything setup (include path, toolchain etc ..) to compile a module. This second time through the Makefile, the kbuild path is taken, and the module is built as if it was in-tree.
Compiling with your build-system's headers is spectacularly bad news, and may subtle binary incompatibilities that manifest themselves as seemingly bizarre crashes on the target.
As you've already discovered, the kernel is already hardened against this and will refuse to load modules built against the wrong headers. You'll need to build using the same source tree as the existing kernel - including any patches. You might as well at this point rebuild the entire kernel.
The kernel tree is self-contained, so simply cross-compiling it in place will work. If you're adding a driver it's probably easiest to compile it in-tree.
If you want to build any user-space components, you have two solutions:
Pass the --sysroot=<dir> option to gcc, where <dir> is the system root of your target system
Build gcc and binutils to use as their default sysroot
The latter approach is the one that Angstrom uses, and it save a lot of butt-hurt.
You might want to try using crosstool-ng
It takes care of the majority of the work. You only need to bother about the configuration settings you want to enable for kernel compilation.
Here another reference: link

Resources