|
| 1 | +# ch5/lkm_template/Makefile |
| 2 | +# *************************************************************** |
| 3 | +# This program is part of the source code released for the book |
| 4 | +# "Linux Kernel Programming" |
| 5 | +# (c) Author: Kaiwan N Billimoria |
| 6 | +# Publisher: Packt |
| 7 | +# GitHub repository: |
| 8 | +# https://github.com/PacktPublishing/Linux-Kernel-Programming |
| 9 | +# |
| 10 | +# From: Ch 5 : Writing Your First Kernel Module LKMs, Part 2 |
| 11 | +# *************************************************************** |
| 12 | +# Brief Description: |
| 13 | +# A 'better' Makefile template for Linux LKMs (Loadable Kernel Modules); besides |
| 14 | +# the 'usual' targets (the build, install and clean), we incorporate targets to |
| 15 | +# do useful (and indeed required) stuff like: |
| 16 | +# - adhering to kernel coding style (indent+checkpatch) |
| 17 | +# - several static analysis targets (via sparse, gcc, flawfinder, cppcheck) |
| 18 | +# - two 'dummy' dynamic analysis targets (KASAN, LOCKDEP) |
| 19 | +# - a packaging (.tar.xz) target and |
| 20 | +# - a help target. |
| 21 | +# |
| 22 | +# To get started, just type: |
| 23 | +# make help |
| 24 | +# |
| 25 | +# For details, please refer the book, Ch 5. |
| 26 | + |
| 27 | +# To support cross-compiling for kernel modules: |
| 28 | +# For architecture (cpu) 'arch', invoke make as: |
| 29 | +# make ARCH=<arch> CROSS_COMPILE=<cross-compiler-prefix> |
| 30 | +ifeq ($(ARCH),arm) |
| 31 | + # *UPDATE* 'KDIR' below to point to the ARM Linux kernel source tree on your box |
| 32 | + KDIR ?= ~/rpi_work/kernel_rpi/linux |
| 33 | +else ifeq ($(ARCH),arm64) |
| 34 | + # *UPDATE* 'KDIR' below to point to the ARM64 (Aarch64) Linux kernel source |
| 35 | + # tree on your box |
| 36 | + KDIR ?= ~/kernel/linux-4.14 |
| 37 | +else ifeq ($(ARCH),powerpc) |
| 38 | + # *UPDATE* 'KDIR' below to point to the PPC64 Linux kernel source tree on your box |
| 39 | + KDIR ?= ~/kernel/linux-4.9.1 |
| 40 | +else |
| 41 | + # 'KDIR' is the Linux 'kernel headers' package on your host system; this is |
| 42 | + # usually an x86_64, but could be anything, really (f.e. building directly |
| 43 | + # on a Raspberry Pi implies that it's the host) |
| 44 | + KDIR ?= /lib/modules/$(shell uname -r)/build |
| 45 | +endif |
| 46 | + |
| 47 | +# Set FNAME_C to the kernel module name source filename (without .c) |
| 48 | +FNAME_C := miscdrv_rdwr_refcount |
| 49 | + |
| 50 | +PWD := $(shell pwd) |
| 51 | +obj-m += ${FNAME_C}.o |
| 52 | +EXTRA_CFLAGS += -DDEBUG |
| 53 | + |
| 54 | +all: |
| 55 | + @echo |
| 56 | + @echo '--- Building : KDIR=${KDIR} ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} EXTRA_CFLAGS=${EXTRA_CFLAGS} ---' |
| 57 | + @echo |
| 58 | + make -C $(KDIR) M=$(PWD) modules |
| 59 | +install: |
| 60 | + @echo |
| 61 | + @echo "--- installing ---" |
| 62 | + @echo " [First, invoke the 'make' ]" |
| 63 | + make |
| 64 | + @echo |
| 65 | + @echo " [Now for the 'sudo make install' ]" |
| 66 | + sudo make -C $(KDIR) M=$(PWD) modules_install |
| 67 | + sudo depmod |
| 68 | +clean: |
| 69 | + @echo |
| 70 | + @echo "--- cleaning ---" |
| 71 | + @echo |
| 72 | + make -C $(KDIR) M=$(PWD) clean |
| 73 | + rm -f *~ rdwr_test_secret |
| 74 | + |
| 75 | +#--- special case: target to build our user mode test app |
| 76 | +rdwr_test_secret: rdwr_test_secret.c |
| 77 | + ${CROSS_COMPILE}gcc rdwr_test_secret.c -o rdwr_test_secret -Os -Wall |
| 78 | + |
| 79 | +#--------------- More (useful) targets! ------------------------------- |
| 80 | +INDENT := indent |
| 81 | + |
| 82 | +# code-style : "wrapper" target over the following kernel code style targets |
| 83 | +code-style: |
| 84 | + make indent |
| 85 | + make checkpatch |
| 86 | + |
| 87 | +# indent- "beautifies" C code - to conform to the the Linux kernel |
| 88 | +# coding style guidelines. |
| 89 | +# Note! original source file(s) is overwritten, so we back it up. |
| 90 | +indent: |
| 91 | + @echo |
| 92 | + @echo "--- applying kernel code style indentation with indent ---" |
| 93 | + @echo |
| 94 | + mkdir bkp 2> /dev/null; cp -f *.[chsS] bkp/ |
| 95 | + ${INDENT} -linux --line-length95 *.[chsS] |
| 96 | + # add source files as required |
| 97 | + |
| 98 | +# Detailed check on the source code styling / etc |
| 99 | +checkpatch: |
| 100 | + make clean |
| 101 | + @echo |
| 102 | + @echo "--- kernel code style check with checkpatch.pl ---" |
| 103 | + @echo |
| 104 | + $(KDIR)/scripts/checkpatch.pl --no-tree -f --max-line-length=95 *.[ch] |
| 105 | + # add source files as required |
| 106 | + |
| 107 | +#--- Static Analysis |
| 108 | +# sa : "wrapper" target over the following kernel static analyzer targets |
| 109 | +sa: |
| 110 | + make sa_sparse |
| 111 | + make sa_gcc |
| 112 | + make sa_flawfinder |
| 113 | + make sa_cppcheck |
| 114 | + |
| 115 | +# static analysis with sparse |
| 116 | +sa_sparse: |
| 117 | + make clean |
| 118 | + @echo |
| 119 | + @echo "--- static analysis with sparse ---" |
| 120 | + @echo |
| 121 | +# if you feel it's too much, use C=1 instead |
| 122 | + make C=2 CHECK="/usr/bin/sparse" -C $(KDIR) M=$(PWD) modules |
| 123 | + |
| 124 | +# static analysis with gcc |
| 125 | +sa_gcc: |
| 126 | + make clean |
| 127 | + @echo |
| 128 | + @echo "--- static analysis with gcc ---" |
| 129 | + @echo |
| 130 | + make W=1 -C $(KDIR) M=$(PWD) modules |
| 131 | + |
| 132 | +# static analysis with flawfinder |
| 133 | +sa_flawfinder: |
| 134 | + make clean |
| 135 | + @echo |
| 136 | + @echo "--- static analysis with flawfinder ---" |
| 137 | + @echo |
| 138 | + flawfinder *.[ch] |
| 139 | + |
| 140 | +# static analysis with cppcheck |
| 141 | +sa_cppcheck: |
| 142 | + make clean |
| 143 | + @echo |
| 144 | + @echo "--- static analysis with cppcheck ---" |
| 145 | + @echo |
| 146 | + cppcheck -v --force --enable=all -i .tmp_versions/ -i *.mod.c -i bkp/ --suppress=missingIncludeSystem . |
| 147 | + |
| 148 | +# Packaging; just tar.xz as of now |
| 149 | +PKG_NAME := ${FNAME_C} |
| 150 | +tarxz-pkg: |
| 151 | + rm -f ../${PKG_NAME}.tar.xz 2>/dev/null |
| 152 | + make clean |
| 153 | + @echo |
| 154 | + @echo "--- packaging ---" |
| 155 | + @echo |
| 156 | + tar caf ../${PKG_NAME}.tar.xz * |
| 157 | + ls -l ../${PKG_NAME}.tar.xz |
| 158 | + @echo '=== package created: ../$(PKG_NAME).tar.xz ===' |
| 159 | + |
| 160 | +help: |
| 161 | + @echo '=== Makefile Help : additional targets available ===' |
| 162 | + @echo |
| 163 | + @echo 'TIP: type make <tab><tab> to show all valid targets' |
| 164 | + @echo |
| 165 | + |
| 166 | + @echo '--- 'usual' kernel LKM targets ---' |
| 167 | + @echo 'typing "make" or "all" target : builds the kernel module object (the .ko)' |
| 168 | + @echo 'install : installs the kernel module(s) to INSTALL_MOD_PATH (default here: /lib/modules/$(shell uname -r)/)' |
| 169 | + @echo 'clean : cleanup - remove all kernel objects, temp files/dirs, etc' |
| 170 | + |
| 171 | + @echo |
| 172 | + @echo '--- kernel code style targets ---' |
| 173 | + @echo 'code-style : "wrapper" target over the following kernel code style targets' |
| 174 | + @echo ' indent : run the $(INDENT) utility on source file(s) to indent them as per the kernel code style' |
| 175 | + @echo ' checkpatch : run the kernel code style checker tool on source file(s)' |
| 176 | + |
| 177 | + @echo |
| 178 | + @echo '--- kernel static analyzer targets ---' |
| 179 | + @echo 'sa : "wrapper" target over the following kernel static analyzer targets' |
| 180 | + @echo ' sa_sparse : run the static analysis sparse tool on the source file(s)' |
| 181 | + @echo ' sa_gcc : run gcc with option -W1 ("Generally useful warnings") on the source file(s)' |
| 182 | + @echo ' sa_flawfinder : run the static analysis flawfinder tool on the source file(s)' |
| 183 | + @echo ' sa_cppcheck : run the static analysis cppcheck tool on the source file(s)' |
| 184 | + @echo 'TIP: use coccinelle as well (requires spatch): https://www.kernel.org/doc/html/v4.15/dev-tools/coccinelle.html' |
| 185 | + |
| 186 | + @echo |
| 187 | + @echo '--- kernel dynamic analysis targets ---' |
| 188 | + @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' |
| 189 | + @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' |
| 190 | + @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' |
| 191 | + |
| 192 | + @echo |
| 193 | + @echo '--- misc targets ---' |
| 194 | + @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' |
| 195 | + @echo 'help : this help target' |
0 commit comments