Linux kernel module makefile issues - linux

I am trying to learn a little about Linux kernel programming, and after trying a tutorial i am completely stuck.
My makefile is complaining about some sort of "Command not found" error (error 127), so it won't compile it.
I tried searching for a solution, but nothing came up. So I thought I'd try to ask here. Sorry if this is a duplicate.
Here is the error output from the shell:
malt#ubuntu:~/Documents/C$ make
C /usr/src/linux SUBDIRS=/home/malt/Documents/C; modules
/bin/sh: 1: C: not found
/bin/sh: 1: modules: not found
make: [default] Error 127 (ignored)
And here is my makefile:
# Makefile of My First Driver
# if KERNELRELEASE is defined, we've been invoked from the kernel build system
# and can use it's language
ifneq (${KERNELRELEASE},)
obj-m := mfd.o
# otherwise we've been called directly from the commandline.
# 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
Does anyone have any idea as to what is wrong?
Thanks in advance!

Adding to Santosh A's Changes
There shouldn't be ; in PWD := ${shell pwd};. remove it which will solve /bin/sh: 1: modules: not found error.

change keyword make to MAKE as below
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean

Related

How to write a Linux kernel module makefile?

I'm trying to write a simple hello world kernel module. I'm working in Ubuntu 18.04.2 LTS on Virtual Box. In the directory /usr/src I created a directory named hello and inside that hello directory I've created hello.c and a makefile. Here is my makefile:
obj-m += hello.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
When I make the command "sudo make" I get this output:
make -C /lib/modules/5.3.0-28-generic/build M= modules
make[1]: Entering directory '/usr/src/linux-headers-5.3.0-28-generic'
make[2]: *** No rule to make target 'arch/x89/tools/relocs_32.c', needed by 'arch/x86/tools/relocs_32.o'. Stop.
arch/x86/Makefile:232: recipe for target 'archscripts' failed
make[1]: *** [archscripts] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.3.0-28-generic'
makefile:4: recipe for target 'all' failed
make: *** [all] Error 2
I've tried a few variations of my makefile including changing "PWD" to "shell pwd". I've installed all the essential tools and libraries as far as I know. What could be the problem here?
Variable PWD is set by the shell, so your Makefile relies on make invocation to be performed from the shell, as we normally do when type make in the terminal.
But sudo make executes make from a plain user environment. This environment lacks for PWD variable, so your Makefile behaves incorrectly. This can be found from your output:
make -C /lib/modules/5.3.0-28-generic/build M= modules
Use $(shell pwd) expression instead, it is more reliable:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Alternatively, you may call make with root privileges using this way:
sudo /bin/sh -c make
This way make is executed not from the plain root environment, but under an intermediate shell. This shell sets PWD variable.
Update
As noted by #Ian Abbott in the comments, another alternative for $(PWD) is $(CURDIR). Variable CURDIR is set by the make itself (precisely, by GNU Make). See also that question: bash: What is the difference between PWD and CURDIR?.
Your Makefile should look like this
obj-m += hello.o
Then your build command will look like
make -C $KDIR M=$PWD
Where $KDIR is the source tree of your kernel build.
is the way. The rest is handled by the kbuild system.
Please refer to refer to the official documentation for building off-tree modules

How to insert dependent modules into Kernel?

I have a Parrot AR.Drone 2.0 running Ubuntu and I want to connect it to the single board computer using cable. There are no Ethernet ports on the drone so I decided to use USB-Ethernet adapter (D-Link DUB-E100).
After entering uname -a in the terminal I get the following line:
Linux uclibc 2.6.32.9-g980dab2 #1 PREEMPT Mon Oct 6 11:50:23 CEST 2013 armv7l GNU/Linux
I followed this article and instead of module for wifi I used module for USB-Ethernet adapter.
This how I edited Makefile:
TARGET = dub_e100
OBJS = dub_e100.o
MDIR = drivers/net/usb
KDIR = /home/artemii/Downloads/linux
EXTRA_CFLAGS = -DEXPORT_SYMTAB
PWD = $(shell pwd)
DEST = /home/artemii/Downloads/linux/$(MDIR)
obj-m := $(TARGET).o
default:
make -C $(KDIR) SUBDIRS=$(PWD) modules
$(TARGET).o: $(OBJS)
$(LD) $(LD_RFLAG) -r -o $# $(OBJS)
install:
su -c "cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a"
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
.PHONY: modules clean
-include $(KDIR)/Rules.make
After that I compiled the kernel with following lines:
make
export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabi-
make
Leter on I transfer generated 'dub_e100.ko' file into drone and ran the following command line:
insmod dube100.ko
Terminal threw an error insmod: can't insert 'dub_e100.ko': unknown symbol in module, or unknown parameter.
Checking dmesg | tail gives:
usb 1-1:1.0: uevent
dub_e100: Unknown symbol mii_ethtool_sset
dub_e100: Unknown symbol mii_link_ok
dub_e100: Unknown symbol mii_nway_restart
dub_e100: Unknown symbol generic_mii_ioctl
dub_e100: Unknown symbol mii_ethtool_gset
I assume that adapter's module depends on mii module, so I generated mii.ko file with following makefile:
TARGET = dub_e100
OBJS = dub_e100.o
MDIR = drivers/net/usb
KDIR = /home/artemii/Downloads/linux
EXTRA_CFLAGS = -DEXPORT_SYMTAB
PWD = $(shell pwd)
DEST = /home/artemii/Downloads/linux/$(MDIR)
obj-m := $(TARGET).o
obj-m += mii.o
default:
make -C $(KDIR) SUBDIRS=$(PWD) modules
$(TARGET).o: $(OBJS)
$(LD) $(LD_RFLAG) -r -o $# $(OBJS)
install:
su -c "cp -v $(TARGET).ko $(DEST) && /sbin/depmod -a"
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
.PHONY: modules clean
-include $(KDIR)/Rules.make
After that I consiquately run mii.ko and dube100.ko on the drone. All the modules visible in lsmod. But after inserting the adapter to the drone it crushes and reboots. After reboot this modules dessapiar from lsmod.
Is there something I am doing wrong? I might generated or ran modules improperly.
insmod does not handle module dependencies. It's manual page says:
insmod is a trivial program to insert a module into the kernel. Most users will want to use modprobe(8) instead, which is more clever and can handle module dependencies.
Note that you may have to run depmod before the modprobe automatic dependency loading works as intended.

How to provide include directory path in kernel module Makefile

I was learning kernel interrupt using a small demo kernel module
which use these two header include
asm/exception.h
asm/mach/irq.h
My Makefile is
ifeq (${KERNELRELEASE},)
KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
make -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
make -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
else
obj-m := irq_demo.o
endif
The error I am getting
irq_demo.c:9:27: fatal error: asm/exception.h: No such file or directory
#include <asm/exception.h>
I found asm/exception.h in my system in /usr/src/linux-headers-3.16.0-30-generic/arch/arm/include/
[1]But how to include this path in Makefile
[2]Is /usr/src/linux-headers-3.16.0-30-generic/include/asm-generic/ linked with arch/arm/include/asm/ ? if yes , than How ?
First try
adding ARCH=arm after make
i.e.
make ARCH=arm -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
============================= OR =============================
Can you try adding line before make
CARGS = -I /lib/modules/$(shell uname -r)/arch/arm/include/
make $(CARGS) -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules

Makefile for kernel kecho command issue

This a makefile for compiling the kernel module.
# Makefile – makefile of our first driver
#
# if KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
obj-m = first-driver.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /lib/modules/2.6.32-504.8.1.el6.x86_64/build
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
#echo kernel first-driver is ready
#$(kecho) 'Kernel: $# is ready'
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif
.PHONY : install remove
install :
sudo insmod first-driver.ko
remove :
sudo rmmod first-driver
Here I have used echo and kecho as per kernel makefile documantation but it giving the following error:
make -C /lib/modules/2.6.32-504.8.1.el6.x86_64/build SUBDIRS=/home/betatest/Device-Driver-Test modules
make[1]: Entering directory '/usr/src/kernels/2.6.32-504.8.1.el6.x86_64'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/usr/src/kernels/2.6.32-504.8.1.el6.x86_64'
kernel first-driver is ready
make: Kernel: default is ready: Command not found
Makefile:16: recipe for target 'default' failed
make: *** [default] Error 127
I am using GNU make version 4.1 and gcc version 4.4.7 where am I going wrong. Thanks.....
What is kecho variable's is assigned to? in the line #$(kecho) 'Kernel: $# is ready' kecho's value is null so the make considers only #$(kecho) 'Kernel: $# is ready' as a rule.
Did you forget to assign kecho to something at the beginning of the file? Like
kecho='echo'

Makefile:10: recipe for target 'modules' failed on multiple debian distros

FIXED
The problem was that I had spaces somewhere in the path to my source directory.
In this case, "Source Builds" had a space and screwed everything up.
Make sure you don't have any spaces anywhere in your folder names between root and your make directory.
So this error:
make[1]: ** No rule to make target 'Builds/ digimend-kernel-drivers-master'. Stop.
Came from the space in: ~/Source Builds/digimend-kernel-drivers-master
debian wheezy, jessie and now simplice 6 sid
I installed the build essentials package
the linux headers package for my kernel
ive tried on kernel 3.2.04, 3.16 and now 3.12
gcc version 4.9.2 (Debian 4.9.2-8)
GNU Make 4.0
this is what i get when i try to make.
willy#semplice:~/Source Builds/digimend-kernel-drivers-master$ make
make -C /lib/modules/3.12-7.semplice.0-desktop-686/build SUBDIRS=/home/willy/Source Builds/digimend-kernel-drivers-master modules
make[1]: Entering directory '/usr/src/linux-headers-3.12-7.semplice.0-desktop-686'
make[1]: *** No rule to make target 'Builds/digimend-kernel-drivers-master'. Stop.
make[1]: Leaving directory '/usr/src/linux-headers-3.12-7.semplice.0-desktop-686'
Makefile:10: recipe for target 'modules' failed
make: *** [modules] Error 2
Heres the makefile
ifneq ($(KERNELRELEASE),)
obj-m := hid-huion.o hid-uclogic.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
UDEV_RULES := /lib/udev/rules.d/70-hid-rebind.rules
DEPMOD_CONF := /etc/depmod.d/digimend.conf
HID_REBIND := /sbin/hid-rebind
modules modules_install clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $#
install: modules_install
install -D -m 0644 digimend.conf $(DEPMOD_CONF)
depmod -a
install hid-rebind $(HID_REBIND)
install -m 0644 hid-rebind.rules $(UDEV_RULES)
udevadm control --reload
uninstall:
rm -vf $(UDEV_RULES) $(HID_REBIND) $(DEPMOD_CONF) \
/lib/modules/*/extra/hid-huion.ko \
/lib/modules/*/extra/hid-uclogic.ko
udevadm control --reload
depmod -a
endif
what is going on here... I am getting sad
FIXED
The problem was that I had spaces somewhere in the path to my source directory.
In this case, "Source Builds" had a space and screwed everything up.
Make sure you don't have any spaces anywhere in your folder names between root and your make directory.
So this error:
make[1]: ** No rule to make target 'Builds/ digimend-kernel-drivers-master'. Stop.
Came from the space in: ~/Source Builds/digimend-kernel-drivers-master
– user4369678

Resources