Override some options for HOSTCFLAGS when building kernel modules - makefile

Is that possible to set O0 or O1 when building a specific kernel module? The reason is that I need to use KGDB to debug a specific kernel module which prefer the compile not optimize the code.
The HOSTCFLAGS is set to O2 by default in the Makefile in kernel source's root dir, which makes some kernel debugging not functionally well(e.g.: variable optimized out).
It should not be good if set O0/O1 at the Makefile in root dir, which changes the compile behavior for the whole kernel source.

Related

GNU Make: support some targets not parallel without add depends

the Makefile is something like this.
all: host kernel app;
host: host/kconfig;
kernel: kernel/compile kernel/install;
app: app/busybox app/switch app/wifi;
app/busybox: app/busybox/compile app/busybox/install;
app/switch: app/switch/compile app/switch/install;
app/wifi: app/wifi/compile app/wifi/install;
app/busybox/compile:
make -C busybox
the host target build host tools. the kernel target build kernel. the app target build userspace application and kernel modules.
I want to support parallel build. but the parallel strategy and reasons are:
host/kernel/app can't be parallel
build kernel only after host is built, build app only after kernel is built.
but I don't want kernel depends on host, app depends on kernel.
because when I build app solely I don't want the kernel is built.
some app can't be parallel
switch and wifi are kernel modules, so app/switch/compile and app/wifi/compile can't be parallel.
Now I add .NOTPARALLEL to Makefile, so only sub Makefile in rule are parallel, but some targets can actually be parallel, e.g. app/busybox app/boa.
How can I write Makefile to support this flexible parallel build.
Based on your comment what you are really wanting is for the app target to be rebuilt when the kernel target rebuilds, but you don't want to rebuild the kernel target automatically whenever you ask to rebuild the app target.
I'm not sure what this has to do with parallel builds though...??
To do this, just don't have the app target depend on the kernel target at all. If you want to have app rebuild when you do update kernel, then have app depend on some file that gets updated when you rebuild kernel, but don't have a make target describing how to build that file... make will consider it to be like any other source file.
Something like this:
app: .build_target
...build app...
kernel:
....build kernel...
touch .build_target
Or, if the kernel target builds some other file you can have app depend on that and you don't need the touch. Now when you build app it will only get rebuilt if .build_target is newer, but it won't try to build kernel (because make doesn't know how to build .build_target) unless you specifically say make kernel.
ETA
If you want make kernel app to build both, you can do it like this:
app: $(filter kernel,$(MAKECMDGOALS))
This way if kernel appears as a command-line goal then app will depend on it, and if it doesn't it won't.

Cross compilation of libraries that dynamically or statically linked with system libraries

I am trying to cross compile some dependency libs for RaspberryPi target system, and host system is Linux with GCC compiler. For example, let's say that one of those libs has dependency on linkage stage and being linked with one of the system's static or dynamic libraries.
How this case is resolved by linker? (Because those .a or .so files can be different on target system, so probably program on RaspberryPi will crash in this case). How to make it work in a right way?
The build environment that the cross-compiler provides is more accurately described as a cross-toolchain. It needs to provide everything you need: Not just the compiler, but also the assembler, linker, and all run-time support libraries. That includes a C library (maybe glibc, maybe something else), the GCC run-time library (libgcc and libgcc_s), and the C++ run-time library (libstdc++). But the build environment also needs copies of all the libraries your software needs to build, typically both header files and static libraries or dynamic shared objects for the target. In particular, you cannot use the installed header files on the host because they might have the wrong definitions and declarations for the target.
Some programmers simply copy their dependencies (which are not system libraries) into their source tree, so that the cross-build environment can stay minimal. But then these libraries have to be tracked and updated as part of the project, which can be cumbersome.

Is ld called at both compile time and runtime?

I am trying to understand how linking and loading work. My understanding is that the Unix program "ld" contains both linking and loading functionality. When gcc is invoked, after preprocessing, compiling, and assembling, the linker is called which links all object files and .a files into an executable, along with minimal instructions for how shared libraries should be "connected" (what is the correct terminology here?) at runtime. This linker is ld.
At runtime, my understanding is that the executable is loaded into memory, although I'm not sure how. My specific questions are as follows:
1) Are shared object files being "linked" at compile time, or is there another word for what is happening?
2) At runtime, is ld being called for a second time? How can I see proof of this for my executable (on Linux and on MacOS)?
3) Are shared object files being "linked" at runtime, or is there another word for the process when shared objects are read from the location in LD_LIBRARY_PATH at runtime?
Thanks!
Is ld called at both compile time and runtime?
No: ld is not called at either compile or runtime.
When gcc is invoked, after preprocessing, compiling, and assembling, the linker is called which links all object files and .a files into an executable
Most moderately complicated programs use separate compilation and linking steps.
At compilation, a set of relocatable object files is produced (preprocessing, compilation and assembling are invoked at that step). Optionally the .o files are archived into an archive library (libsomething.a).
Then a link step is performed (often this is called "static linking", to differentiate this step from "dynamic loading" that will happen at runtime), producing an executable, or a shared library. Only at this step is /usr/bin/ld is invoked. On Linux, ld is part of the binutils package.
along with minimal instructions for how shared libraries should be "connected"
The linker records which shared libraries are required at runtime, and possibly which versions of libraries or symbols are required.
It also records which runtime loader should be used to load the required shared libraries.
At runtime, my understanding is that the executable is loaded into memory, although I'm not sure how.
The kernel loads executable into memory, and checks whether runtime loader was requested at static link time. If it was, the dynamic loader is also loaded into memory, and execution control is passed to it (instead of the main executable).
It is then the job of the dynamic loader to examine the executable for instructions on which other libraries are required, check whether correct versions can be found, loading them into memory, and arranging things such that symbol resolution will work between the main executable and the shared libraries. This is the runtime loading step, often also called dynamic linking.
The dynamic loader can be part of the OS, but on Linux it's part of libc (GLIBC, uClibc and musl each have their own loader).
No. ld is linking as in creating a library or exe, ld*.so is the loading part. Also ld*.so is part of the OS, not the gcc suite afaik. ld is generally part of (GNU) binutils on a gcc based system (but e.g. usually LLVM lld in a LLVM based system)
ld*.so is ld-linux-{arch}.so.2 on Linux and /libexec/ld-elf.so on e.g. FreeBSD.

How do I recompile a single Linux kernel module?

I need to build mmc_block.ko but with MMC_BLOCK_MINORS=16. I do not wish to build the entire kernel. I am using Ubuntu 15.10. How do I do this?
Dpending on how the Makefile has been written, a module can be compiled out of the kernel tree or in the kernel tree.
Concerning your specific example, I assume the module is the one shipped with the kernel and therefore the Makefile has been written for in-tree compilation. In this case, you can just type make modules to rebuild the module, provided that the kernel has been already compiled (which is a mandatory condition also for out-of-the-tree compilation).

How does the kernel Makefile magically knows what to compile?

I'm new in writing Linux device driver, and I'm wondering how the kernel Makefile magically knows what to compile. To illustrate what I don't understand, consider the following case:
I did a #include <linux/irq.h> in my driver code and I'm able to find the header file irq.h in the kernel directory KDIR/include/linux. However, this is only the header file, so I thought the irq.c source code must be out there somewhere. Hence, I looked into the KDIR/arch/arm searching for irq.c (since I'm using the ARM architecture). My confusion begins here when I found really many irq.c inside KDIR/arch/arm. To simply list a few, I got:
KDIR/arch/arm/mach-at91/irq.c
KDIR/arch/arm/mach-davinci/irq.c
KDIR/arch/arm/mach-omap1/irq.c
KDIR/arch/arm/mach-orion5x/irq.c
many more...
In my Makefile, I have a line like this:
$(MAKE) -C $(KDIR) M=$(PWD) CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm modules
So I understand that the kernel Makefile knows that I'm using the ARM architecture, but under KDIR/arch/arm/, there are so many irq.c with the same name. I'm guessing that the mach-davinci/irq.c is compiled since davinci is the cpu name I'm using. But then, how can the kernel Makefile knows this is the one to compile? Or if I would like to have a look for the irq.c that I'm actually using, which one should I refer to?
I believe there must be a way to know this besides reading the long kernel Makefile. Thanks for any help!
Beyond the ARCH variable, you can also choose the system type (mach) from the configuration menu (there is actually a sub-menu called "System type" when you type make menuconfig for instance). This selection will include and compile all files under linux2.6/arch/$ARCH/mach-$MACH, and in your case this is how only one irq.c gets compiled.
That aside, it is interesting to understand how the kernel chooses which files to compile. The mechanism behind this is called Kconfig, and it is what allows you to precisely configure your kernel using make menuconfig and others, to compile a module from the outside like you are doing, and to select the right files to compile from simple Makefiles. While it is simple to use, its internals are rather complex - but this article, although rather old, explains it rather well:
http://www.linuxjournal.com/article/6568
To make a very long story short, there's a target make config, which you can trace. That one generates .config, that is your main guideline to making dependencies and controlling what will be compiled, what not, what as module and what will be compiled into the kernel.
This guide should give you a basic understanding of building a kernel module (and I assume that's where you want to start with your driver).

Resources