1
- # Makefile
1
+ # ch5/lkm_template/Makefile
2
+ # ***************************************************************
3
+ # This program is part of the source code released for the book
4
+ # "Linux Kernel Programming" 2E
5
+ # (c) Author: Kaiwan N Billimoria
6
+ # Publisher: Packt
7
+ # GitHub repository:
8
+ # https://github.com/PacktPublishing/Linux-Kernel-Programming_2E
9
+ #
10
+ # From: Ch 5 : Writing Your First Kernel Module LKMs, Part 2
2
11
# ***************************************************************
3
12
# Brief Description:
4
13
# A 'better' Makefile template for Linux LKMs (Loadable Kernel Modules); besides
13
22
# To get started, just type:
14
23
# make help
15
24
#
16
- # For details on this so-called 'better' Makefile, please refer my book
17
- # 'Linux Kernel Programming' 2nd Ed, Packt, 2023, Chapter 5, section
25
+ # For details, please refer the book, Ch 5, section
18
26
# 'A "better" Makefile template for your kernel modules'.
27
+ #
28
+ # AUTHOR : Kaiwan N Billimoria
29
+ # DESCRIPTION : A simple kernel module 'better' Makefile template
30
+ # LICENSE : Dual MIT/GPL
31
+ # VERSION : 0.2
19
32
20
33
# ------------------------------------------------------------------
21
- # Set FNAME_C to the kernel module name source filename (without .c)
34
+ # IMPORTANT : Set FNAME_C to the kernel module name source filename (without .c).
22
35
# This enables you to use this Makefile as a template; just update this variable!
23
36
# As well, the MYDEBUG variable (see it below) can be set to 'y' or 'n' (no being
24
37
# the default)
25
38
FNAME_C := lowlevel_mem
26
39
ifeq ($(FNAME_C ) ,)
27
- $(error You MUST pass the C file like this :\
28
- make FNAME_C=csrc-filename-without-.c target-name)
29
- else
30
- $(info [FNAME_C = $(FNAME_C)])
40
+ $(error ERROR : you Must set the FNAME_C variable in the Makefile)
31
41
endif
32
42
# ------------------------------------------------------------------
33
43
34
- # To support cross-compiling for kernel modules:
44
+ # --- To support cross-compiling for kernel modules
35
45
# For architecture (cpu) 'arch', invoke make as:
36
46
# make ARCH=<arch> CROSS_COMPILE=<cross-compiler-prefix>
47
+ # F.e. to cross-compile for the AArch64:
48
+ # make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
49
+ #
50
+ # Alternately:
51
+ # export ARCH=<arch>
52
+ # export CROSS_COMPILE=<cross-compiler-prefix>
53
+ # make
54
+ #
37
55
# The KDIR var is set to a sample path below; you're expected to update it on
38
- # your box to the appropriate path to the kernel src tree for that arch.
56
+ # your box to the appropriate path to the kernel source tree for that arch.
39
57
ifeq ($(ARCH ) ,arm)
40
58
# *UPDATE* 'KDIR' below to point to the ARM Linux kernel source tree on your box
41
- KDIR ?= ~/rpi_work/kernel_rpi /linux
59
+ KDIR ?= ~/arm_prj/kernel /linux
42
60
else ifeq ($(ARCH),arm64)
43
61
# *UPDATE* 'KDIR' below to point to the ARM64 (Aarch64) Linux kernel source
44
62
# tree on your box
45
- KDIR ?= ~/kernel/linux-5.4
63
+ KDIR ?= ~/arm64_prj/ kernel/linux-5.10.60
46
64
else ifeq ($(ARCH),powerpc)
47
65
# *UPDATE* 'KDIR' below to point to the PPC64 Linux kernel source tree on your box
48
- KDIR ?= ~/kernel/linux-5.0
66
+ KDIR ?= ~/ppc_prj/ kernel/linux-5.4
49
67
else
50
68
# 'KDIR' is the Linux 'kernel headers' package on your host system; this is
51
69
# usually an x86_64, but could be anything, really (f.e. building directly
52
70
# on a Raspberry Pi implies that it's the host)
53
71
KDIR ?= /lib/modules/$(shell uname -r) /build
54
72
endif
73
+ # ---
55
74
56
75
# Compiler
57
76
CC := $(CROSS_COMPILE ) gcc
58
- # CC := clang
77
+ # CC := clang
78
+ STRIP := ${CROSS_COMPILE}strip
59
79
60
80
PWD := $(shell pwd)
61
81
obj-m += ${FNAME_C}_lkm.o
62
82
lowlevel_mem_lkm-objs := ${FNAME_C}.o ../../klib.o
63
83
64
84
# --- Debug or production mode?
65
- # Set the MYDEBUG variable accordingly to y/n resp.
85
+ # Set the MYDEBUG variable accordingly to y/n resp. We keep it off (n) by default.
66
86
# (Actually, debug info is always going to be generated when you build the
67
87
# module on a debug kernel, where CONFIG_DEBUG_INFO is defined, making this
68
- # setting of the ccflags-y (or EXTRA_CFLAGS) variable mostly redundant (besides
69
- # the -DDEBUG).
88
+ # setting of the ccflags-y (or the older EXTRA_CFLAGS) variable mostly redundant
89
+ # (besides the still useful -DDEBUG).
70
90
# This simply helps us influence the build on a production kernel, forcing
71
91
# generation of debug symbols, if so required. Also, realize that the DEBUG
72
92
# macro is turned on by many CONFIG_*DEBUG* options; hence, we use a different
73
93
# macro var name, MYDEBUG).
74
94
MYDEBUG := n
95
+ DBG_STRIP := y
75
96
ifeq (${MYDEBUG}, y)
76
-
77
97
# https://www.kernel.org/doc/html/latest/kbuild/makefiles.html#compilation-flags
78
98
# EXTRA_CFLAGS deprecated; use ccflags-y
79
99
ccflags-y += -DDEBUG -g -ggdb -gdwarf-4 -Wall -fno-omit-frame-pointer -fvar-tracking-assignments
100
+ DBG_STRIP := n
80
101
else
81
- INSTALL_MOD_STRIP := 1
82
102
ccflags-y += -UDEBUG
83
103
endif
84
104
# We always keep the dynamic debug facility enabled; this allows us to turn
85
105
# dynamically turn on/off debug printk's later... To disable it simply comment
86
106
# out the following line
87
107
ccflags-y += -DDYNAMIC_DEBUG_MODULE
88
-
89
108
KMODDIR ?= /lib/modules/$(shell uname -r)
90
- STRIP := ${CROSS_COMPILE}strip
91
109
92
- # gcc-10 issue:
93
- # ccflags-y += $(call cc-option,--allow-store-data-races)
110
+ # Gain access to kernel configs
111
+ include $(KDIR ) /.config
112
+
113
+ # Strip the module? Note:
114
+ # a) Only strip debug symbols else it won't load correctly
115
+ # b) WARNING! Don't strip modules when using CONFIG_MODULE_SIG* crytographic security
116
+ ifdef CONFIG_MODULE_SIG
117
+ DBG_STRIP := n
118
+ endif
119
+ ifdef CONFIG_MODULE_SIG_ALL
120
+ DBG_STRIP := n
121
+ endif
122
+ ifdef CONFIG_MODULE_SIG_FORCE
123
+ DBG_STRIP := n
124
+ endif
125
+
94
126
95
127
all :
96
128
@echo
97
- @echo ' --- Building : KDIR=${KDIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} ccflags-y=${ccflags-y} ---'
129
+ @echo ' --- Building : KDIR=${KDIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} ccflags-y=" ${ccflags-y}" MYDEBUG=${MYDEBUG} DBG_STRIP=${DBG_STRIP } ---'
98
130
@${CC} --version| head -n1
99
131
@echo
100
132
make -C $(KDIR ) M=$(PWD ) modules
101
- $(shell [ "${MYDEBUG}" != "y" ] && ${STRIP} --strip-debug ./${FNAME_C}.ko)
133
+ if [ " ${DBG_STRIP} " = " y" ]; then \
134
+ ${STRIP} --strip-debug ${FNAME_C} .ko ; \
135
+ fi
102
136
install :
103
137
@echo
104
138
@echo " --- installing ---"
@@ -107,10 +141,11 @@ install:
107
141
@echo
108
142
@echo " [Now for the 'sudo make install' ]"
109
143
sudo make -C $(KDIR ) M=$(PWD ) modules_install
110
- @echo " sudo depmod"
111
144
sudo depmod
112
- @echo " [If !debug, stripping debug info from ${KMODDIR} /extra/${FNAME_C} .ko]"
113
- $(shell if [ "${MYDEBUG}" != "y" ]; then sudo ${STRIP} --strip-debug ${KMODDIR}/extra/${FNAME_C}.ko; fi)
145
+ @echo " [If !debug and !(module signing), stripping debug info from ${KMODDIR} /extra/${FNAME_C} .ko]"
146
+ if [ " ${DBG_STRIP} " = " y" ]; then \
147
+ sudo ${STRIP} --strip-debug ${KMODDIR}/extra/${FNAME_C}.ko ; \
148
+ fi
114
149
nsdeps :
115
150
@echo " --- nsdeps (namespace dependencies resolution; for possibly importing ns's) ---"
116
151
make -C $(KDIR ) M=$(PWD ) nsdeps
@@ -119,10 +154,11 @@ clean:
119
154
@echo " --- cleaning ---"
120
155
@echo
121
156
make -C $(KDIR ) M=$(PWD ) clean
122
- # from 'indent'
157
+ # from 'indent'; comment out if you want the backup kept
123
158
rm -f *~
124
159
125
- # Any usermode programs to build? Insert the build target(s) here
160
+ # Any usermode programs to build? Insert the build target(s) below
161
+
126
162
127
163
# --------------- More (useful) targets! -------------------------------
128
164
INDENT := indent
@@ -168,12 +204,11 @@ sa_sparse:
168
204
ifeq (,$(shell which sparse) )
169
205
$(error ERROR: install sparse first)
170
206
endif
171
-
172
207
make clean
173
208
@echo
174
209
@echo "--- static analysis with sparse ---"
175
210
@echo
176
- # if you feel it's too much, use C=1 instead
211
+ # If you feel it's too much, use C=1 instead
177
212
# NOTE: deliberately IGNORING warnings from kernel headers!
178
213
make -Wsparse-all C=2 CHECK="/usr/bin/sparse --os=linux --arch=$(ARCH)" -C $(KDIR) M=$(PWD) modules 2>&1 |egrep -v "^\./include/.*\.h|^\./arch/.*\.h"
179
214
@@ -207,29 +242,30 @@ endif
207
242
@echo
208
243
cppcheck -v --force --enable=all -i .tmp_versions/ -i *.mod.c -i bkp/ --suppress=missingIncludeSystem .
209
244
210
- # Packaging; just tar.xz as of now
211
- PKG_NAME := ${FNAME_C}
245
+ # Packaging: just generates a tar.xz of the source as of now
212
246
tarxz-pkg :
213
- rm -f ../${PKG_NAME } .tar.xz 2> /dev/null
247
+ rm -f ../${FNAME_C } .tar.xz 2> /dev/null
214
248
make clean
215
249
@echo
216
250
@echo " --- packaging ---"
217
251
@echo
218
- tar caf ../${PKG_NAME } .tar.xz *
219
- ls -l ../${PKG_NAME } .tar.xz
220
- @echo ' === package created: ../$(PKG_NAME ).tar.xz ==='
221
- @echo ' Tip: when extracting, to extract into a dir of the same name as the tar file,'
222
- @echo ' do: tar -xvf ${PKG_NAME }.tar.xz --one-top-level'
252
+ tar caf ../${FNAME_C } .tar.xz *
253
+ ls -l ../${FNAME_C } .tar.xz
254
+ @echo ' === package created: ../$(FNAME_C ).tar.xz ==='
255
+ @echo ' TIP: When extracting, to extract into a directory with the same name as the tar file, do this: '
256
+ @echo ' tar -xvf ${FNAME_C }.tar.xz --one-top-level'
223
257
224
258
help :
225
259
@echo ' === Makefile Help : additional targets available ==='
226
260
@echo
227
- @echo ' TIP: type make <tab><tab> to show all valid targets'
228
- @echo
261
+ @echo ' TIP: Type make <tab><tab> to show all valid targets'
262
+ @echo ' FYI: KDIR=${KDIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} ccflags-y="${ccflags-y}" MYDEBUG=${MYDEBUG} DBG_STRIP=${DBG_STRIP} '
229
263
264
+ @echo
230
265
@echo '--- 'usual' kernel LKM targets ---'
231
266
@echo 'typing "make" or "all" target : builds the kernel module object (the .ko)'
232
- @echo 'install : installs the kernel module(s) to INSTALL_MOD_PATH (default here: /lib/modules/$(shell uname -r)/)'
267
+ @echo 'install : installs the kernel module(s) to INSTALL_MOD_PATH (default here: /lib/modules/$(shell uname -r)/).'
268
+ @echo ' : Takes care of performing debug-only symbols stripping iff MYDEBUG=n and not using module signature'
233
269
@echo 'nsdeps : namespace dependencies resolution; for possibly importing namespaces'
234
270
@echo 'clean : cleanup - remove all kernel objects, temp files/dirs, etc'
235
271
@@ -246,17 +282,17 @@ help:
246
282
@echo ' sa_gcc : run gcc with option -W1 ("Generally useful warnings") on the source file(s)'
247
283
@echo ' sa_flawfinder : run the static analysis flawfinder tool on the source file(s)'
248
284
@echo ' sa_cppcheck : run the static analysis cppcheck tool on the source file(s)'
249
- @echo 'TIP: use coccinelle as well (requires spatch) : https://www.kernel.org/doc/html/v4.15 /dev-tools/coccinelle.html'
285
+ @echo 'TIP: use Coccinelle as well: https://www.kernel.org/doc/html/v6.1 /dev-tools/coccinelle.html'
250
286
251
287
@echo
252
288
@echo '--- kernel dynamic analysis targets ---'
253
289
@echo 'da_kasan : DUMMY target: this is to remind you to run your code with the dynamic analysis KASAN tool enabled; requires configuring the kernel with CONFIG_KASAN On, rebuild and boot it'
254
290
@echo 'da_lockdep : DUMMY target: this is to remind you to run your code with the dynamic analysis LOCKDEP tool (for deep locking issues analysis) enabled; requires configuring the kernel with CONFIG_PROVE_LOCKING On, rebuild and boot it'
255
- @echo 'TIP: best to build a debug kernel with several kernel debug config options turned On, boot via it and run all your test cases'
291
+ @echo 'TIP: Best to build a debug kernel with several kernel debug config options turned On, boot via it and run all your test cases'
256
292
257
293
@echo
258
294
@echo '--- misc targets ---'
259
295
@echo 'tarxz-pkg : tar and compress the LKM source files as a tar.xz into the dir above; allows one to transfer and build the module on another system'
260
- @echo ' Tip: when extracting, to extract into a dir of the same name as the tar file,'
261
- @echo ' do: tar -xvf ${PKG_NAME }.tar.xz --one-top-level'
296
+ @echo ' TIP: When extracting, to extract into a directory with the same name as the tar file, do this: '
297
+ @echo ' tar -xvf ${FNAME_C }.tar.xz --one-top-level'
262
298
@echo 'help : this help target'
0 commit comments