Creating a debug target in Linux 2.6 driver module makefile - linux

I'm trying to be able to execute "make debug" at the command line and it will build my driver module with the -DDEBUG_OUTPUT define, which will cause certain sections of code to be compiled in.
In 2.4 kernel makefiles, this is pretty easy. I just create a debug: target and included "-DDEBUG_OUTPUT" in the cc compilation command arguments for that target. Easy.
Unfortunately (for me), 2.6 completely changed how modules are compiled, and I can ONLY seem to find the trivial "all" and "clean" examples, which don't show adding custom defines at compilation time.
I tried this:
debug:
make -C $(KERNEL_DIR) SUBDIRS='pwd' -DDEBUG_OUTPUT modules
and got a complaint from make.
I've also tried:
.PHONY: debug
debug:
make -C $(KERNEL_DIR) SUBDIRS='pwd' EXTRA_CFLAGS="$(EXTRA_CFLAGS) -DDEBUG_OUTPUT" modules
but it is not seeing what EXTRA_CFLAGS contains. I can see from the command line output that it does correctly append the -D onto the existing EXTRA_CFLAGS, which includes the -I for includes dir. However, the driver file won't compile now because it cannot find the includes dir...so somehow it is not seeing what EXTRA_CFLAGS contains.

A "-D" option is not meant to be passed to make: it is a C preprocesseor (cpp) option.
To define DEBUG_OUTPUT for your build you have to add the following line to your Kbuild file:
EXTRA_CFLAGS = -DDEBUG_OUTPUT
Afterwards you can call, as usual:
make -C $(KERNEL_DIR) M=`pwd`
EDIT: If you don't want to edit the Kbuild file, you can have a debug target like this:
INCLUDES="-Imy_include_dir1 -Imy_include_dir2"
.PHONY: debug
debug:
$(MAKE) -C $(KDIR) M=`pwd` EXTRA_CFLAGS="$(INCLUDES) -DDEBUG_OUTPUT"
EDIT#2:
MY_CFLAGS=-DFOO -DBAR -Imydir1
all:
$(MAKE) -C $(KDIR) M=`pwd` EXTRA_CFLAGS="$(MY_CFLAGS)"
debug: MY_CFLAGS+=-DDEBUG_OUTPUT
debug:
$(MAKE) -C $(KDIR) M=`pwd` EXTRA_CFLAGS="$(MY_CFLAGS)"

Related

GET WARNING: modpost: missing MODULE_LICENSE() when LKM is Compiled with Multiple Src files

I have a LKM named RtmNetlinkLKM.c and compiles and run fine. The moment I update its Makefile to compile with other src files, it starts giving warning:
WARNING: modpost: missing MODULE_LICENSE()
The following MODULE_LICENSE("GPL"); is already present in kernel module file.
Previous Makefile, module compiles fine
obj-m += RtmNetlinkLKM.o
all:
make -C /lib/modules/`uname -r`/build M=$(PWD) modules
clean:
make -C /lib/modules/`uname -r`/build M=$(PWD) clean
updated Makefile, module now compiles with a warning
obj-m += RtmNetlinkLKM.o
RtmNetlinkLKM-objs += rt_kern.o gluethread/glthread.o << Added two more sources
all:
make -C /lib/modules/`uname -r`/build M=$(PWD) modules
clean:
make -C /lib/modules/`uname -r`/build M=$(PWD) clean
rm -f rt_kern.o
rm -f gluethread/glthread.o
When compiled using second Makefile, it gives stated warning. When I add MODULE_LICENSE("GPL") in gluethread/glthread.c , warning goes away. I don't understand, why do I need to add "GPL" license in glthread.c when it is not a module but contain functions to be used by module (It is a linked list mini-library). Why doesn't it complain with other src file rt_kern.c in a similar way. I had never made any changes in original module file RtmNetlink.c throughout this process.
Thanks to #Gautham Kantharaju in link provided by #Tsyvarev for solving my problem. While compiling multiple source files into a single module, the main reason for the warning seems to be, ".. it is not possible to have the module name and the source name to be the same."
If anyone else has the same question, I think following Makefile should solve the issue.
# give your module a different Name
obj-m += newModuleName.o
newModuleName-objs += RtmNetlinkLKM.o rt_kern.o gluethread/glthread.o
all:
make -C /lib/modules/`uname -r`/build M=$(PWD) modules
clean:
make -C /lib/modules/`uname -r`/build M=$(PWD) clean

Linux Kernel Module - Sharing variables between source files

I'm trying to link a kernel module to a non-LKM source file. The problem is, I'm running into some issues. The names of the two files are chardev.c (the LKM) and foo.c.
My Makefile:
obj-m += chardev.o
obj-y += foo.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
$(CC) test.c -o test
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
rm test
Inside of chardev.c I've the following line of code: extern int foo;, and inside foo I've the following line of code: int foo = 123;. (Both lines are at file-scope.)
When running make I'm getting the following output:
make -C /lib/modules/4.4.0-31-generic/build/ M=/home/kylemart/Desktop/Device-Driver modules
make[1]: Entering directory `/usr/src/linux-headers-4.4.0-31-generic'
CC [M] /home/kylemart/Desktop/Device-Driver/chardev.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "foo" [/home/kylemart/Desktop/Device-Driver/chardev.ko] undefined!
CC /home/kylemart/Desktop/Device-Driver/chardev.mod.o
LD [M] /home/kylemart/Desktop/Device-Driver/chardev.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.4.0-31-generic'
cc test.c -o test
Seems things aren't linking properly. What am I doing wrong?
EDIT:
This seems to work, but there's a problem:
obj-m += chardev.o
chardev-objs += foo.o
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
$(CC) test.c -o test
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
rm test
Although it compiles without warnings, after installing the compiled module (i.e. sudo insmod chardev.ko) there isn't a new device present in /dev. Previously, without trying to link source files, installing kernel modules as previously stated created a device file. That said, the device is present when running lsmod.
Your all target builds only the module, but not the kernel so that the foo symbol does not exist there.
When compiling a source (here: foo.c) into the kernel, you have to integrate the makefile into the kernel source. E.g. you have to add
obj-y += my-driver/
to the makefile in the previous directory and build the whole kernel. You should probably remove your all: and clean: targets from the makefile to avoid conflicts with kernel builtin rules.
foo.c must contain
EXPORT_SYMBOL(foo);
or
EXPORT_SYMBOL_GPL(foo);
The second makefile...
will generate only the chardev.ko module which is built from only foo.c; chardev.c will not be used for it. When you really want this, you have to change file names; e.g.
obj-m += chardev.o
chardev-objs = chardev-core.o foo.o

how to compile linux kernel module with -ggdb flag

I modify my module Makefile to make kernel module with -ggdb flag,
KERNROOT := /lib/modules/$(shell uname -r)/build
ccflags-y += -ggdb3
#ccflags-y += -g
test:
$(MAKE) $(ccflags-y) -C $(KERNROOT) M=$(shell pwd)
But it didn't work. The fail message:
make: invalid option -- 'g'
make: invalid option -- 'g'
make: invalid option -- '3'
Usage: make [options] [target] ..
.
Any help? Thanks a lot.
try enabling it through .config file, configurations are taken from there even for compiling the external modules. you can also refer from here you can also enable it from
make menuconfig > Kernel Hacking > Compile kernel with debug info
some reference | some more reference | kernel doc regarding gdb | kernel reference for gdb
When calling make, put KCFLAGS=-ggdb3 prior to any target you're using. For example, to make vmlinux, modules, and bzImage with ggdb3 symbols enabled, run make KCFLAGS=-ggdb3 all.
Note that this is NOT the same as just enabling kernel debug symbols as described in the other answer. The -ggdb3 flag adds additional information to the symbol file that is not included by default (such as macro definitions).

Compiling out-of-tree kernel module against any kernel source tree on the filesystem

I am trying to compile a module against any source tree on the file system but I am having trouble with the Makefile. This was the original Makefile I had against the kernel specified:
obj-m += new-mod.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
This Makefile would compile correctly, but goal is to have it compile against any source tree. I have tried just:
obj-m += new-mod.o
I thought that "all:" is assumed but I get error:
make: *** No targets. Stop.
I have also added:
all:
to the Makefile with no difference except for error message:
make: Nothing to be done for `all'
I have tried a lot of documentation but no luck. I would greatly appreciate any help.
goal is to have it compile against any source tree
ya you can do it providing a compiled source-code path
just replace make -C /lib/modules/$(shell uname -r)/build M=$PWD modules
with this
make -C <path-to-compiled-src-code> M=$PWD modules
make -C /home/vinay/linux-3.9 M=$PWD modules
try below makefile
Makefile –
# if KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
obj-m := new-mod.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /usr/src/linux
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif
In above you can change KERNEL_SOURCE := /usr/src/linux-->to.--> your sr-code KERNEL_SOURCE := <path to compiled-src-code>
for further info find below liks
while building kernel modules why do we need /lib/modules?
A simple program on linux device driver
How to make a built-in device driver in linux
Build against your custom kernel source ( not the one that is installed),
You can use following steps.
1.download kernel from kernel.org (tar)
2.Extract
3.make x86_64_defconfig
4.make prepare
5.make modules_prepare
Now you have to change Makefile to point to kernel source you had downloaded and extracted. Something similar mentioned in example by Vinay Answer.
Just remember you cannot insmod this module as kernel running and module built is for different kernel.

How to keep asm output from Linux kernel module build

I'm working on a Linux kernel module for a 2.6.x kernel and I need to view the assembly output, though it's currently being done as a temporary file an deleted afterwords. I'd like to have the assembly output mixed with my C source file so I can easily trace where my problem lies. This is for an ARMv6 core and apparently objdump doesn't support this architecture. I've included my makefile below.
ETREP=/xxSourceTreexx/
GNU_BIN=$(ETREP)/arm-none-linux-gnueabi/bin
CROSS_COMPILE := $(GNU_BIN)/arm-none-linux-gnueabi-
ARCH := arm
KDIR=$(ETREP)/linux-2.6.31/
MAKE= CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH) make
obj-m += xxfile1xx.o
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
Objdump does support that architecture. Your executable will be called arm-none-linux-gnueabi-objdump
Assuming gcc and the gnu assembler a more readable output than objdump can be had. Tell the assembler to retain its intermediate code using flags to gcc:
-Wa,-alh=basename.s
And to get basename to be the actual source filename you need to tell make:
-Wa,-alh=$<.s
which will leave piles of foo.c.s files laying around your source directory. The big problem here is that the way gcc works it uses temporary files between code generation and assembly. I can't find a way to make gcc save its intermediates but the assembler is happy to stash a listing for you.
Getting that argument into the Makefile CFLAGS is left as an exercise for the reader (because I kinda hate "make" and hate "gnu info" even more.
To get an assembly language listing of my Linux kernel modules, I added the assembler switches to the kernel scripts/Makefile.build.
#cmd_cc_o_c = $(CC) $(c_flags) -c -o $(#D)/.tmp_$(#F) $<
cmd_cc_o_c = $(CC) $(c_flags) -c -Wa,-alh=$<.lst -o $(#D)/.tmp_$(#F) $<
You could try the flag "-save-temps" to gcc.
It works for me in my embedded project, I haven't tried it on kernel builds.
The proper way is likely to add target dependencies in your module makefile / Kbuild file:
always-m += basename.s
(As kbuild has the proper targets to generate the .s files)
If you are lazy as I am, this could look like:
MOD_NAME := some_module_name
myunits := file1 file2 file3 ... and many more... without .c extension
obj-m := $(MOD_NAME).o
$(MOD_NAME)-y := $(addsuffix .o,$(myunits))
# Comment/uncomment to generate assembly / preprocessor output
always-m += $(addsuffix .s,$(myunits)) $(MOD_NAME).mod.s
always-m += $(addsuffix .i,$(myunits)) $(MOD_NAME).mod.i
(2 bonuses here: assembly for the generated module meta-registration file, and the preprocessor output)

Resources