Makefile for linux kernel module issue - c

I'm writing a kernel module which will be a driver for my chinese Arduino.
I've read many guides about it and Makefiles in them are completely different. Some of them just is not working. And I want to understand how and why:)
For example, I have a simple beginner's code:
#define MODULE
#define __KERNEL__
#include <module.h> // определения для модуля
#include <init.h> // module_init и module_exit
#include <kernel.h> // printk
MODULE_AUTHOR("...");
MODULE_DESCRIPTION("Test module for linux kernel");
int module_start()
{
printk("This is a test module startup message\n");
return 0;
}
void module_stop()
{
printk("Module is dead\n");
return;
}
module_init(module_start);
module_exit(module_stop);
And also I have a Makefile which I found in manual:
CC=gcc
MODFLAGS:= -O2 -Wall -DLINUX
module.o: module.c
$(CC) $(MODFLAGS) -c module.c
So, as I know, my system uses .ko files as a modules. This is the first problem. The second is that this makefile just doesn't work.
When I make, I'm getting the error "missing module.h". But I certainly installed headers. They are in /usr/src/linux-headers-(3.2.0-4-686-pae) and /usr/src/linux-headers-(3.2.0-4-common).
There is no module.h in *pae directory, but it is in *common directory(most of the files are there). So, I just can't compile it neither with gcc nor the makefile.
Thank you for the answers.

The "standard Makefile" for a module build is :
obj-m := hello-1.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
( Creating hello-1.ko from hello-1.c )
The only headers used are the ones in /lib/modules/uname -r/build/include/.
And there is no ``module.h´´ : Please enter like #include <linux/module.h> ( or asm/module.h ).

I can't speak for the .ko module question. I'm not sure what the question really is.
But as for the missing separator error, this is a common Makefile problem. Commands(the $CC line below) in Makefiles must be preceeded with a tab.
To fix, simply add a TAB before your $(CC) line like so:
CC=gcc MODFLAGS:= -O2 -Wall -DLINUX
module.o: module.c
$(CC) $(MODFLAGS) -c module.c
/ \
|
|
TAB

Related

Building linux kernel module

Im a windows driver programmer who is a complete newbie in linux kernel development.I have installed linux kernel headers. I am trying my helloworld module in linux kernel.
#include <linux/init.h>
#include <linux/module.h>
/*MODULE_LICENSE("Dual BSD/GPL");*/
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
following is the code for my module. makefile for my build is
obj-m +=tryout.o
KDIR =/usr/src/linux-headers-4.13.0-37-generic
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
but im getting
'fatal error: linux/init.h: No such file or directory while making this module'. What could be the possible reason? and how can i resolve it?
Your Makefile is mis-configured. In particular you used SUBDIRS whereas you're supposed to use M and your $(PWD) is meaningless, you should use pwd to be simple (or $$PWD); Here's how you should set it up:
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := tryout.o
# any other c files that you would like to include go into
# yourmodule-y := <here> e.g.:
# tryout-y := tryout-1.o tryout-2.o
else
# normal makefile
KDIR ?= /usr/src/linux-headers-4.13.0-37-generic
# you really should set KDIR up as:
# KDIR := /lib/modules/`uname -r`/build
all::
$(MAKE) -C $(KDIR) M=`pwd` $#
# Any module specific targets go under here
#
endif
Configuring your makefile like this will allow you to simply type make in your module directory and it will invoke the Kernel's kbuild subsystem which will in-turn use the kbuild part of your Makefile.
Read up on https://www.kernel.org/doc/Documentation/kbuild/modules.txt for all the different permutations on how to do this. It comes with examples.

New to c, linking error when using a method declared in a header that's included

I'm new to c and I'm trying to use a method from tester in my main.c class.
So here is main.c:
#include <stdbool.h>
#include <stdio.h>
#include "tester.h"
int main(void) {
bool is_valid = isTrue();
}
Here is tester.h:
#include <stdbool.h>
bool isTrue();
Here is tester.c:
#include "tester.h"
bool isTrue() {
return true;
}
And here is what happens when I try to compile:
$ make main tester
gcc -g -O0 -Wall --std=c99 -pedantic -g -O0 main.c -o main
main.c: In function ‘main’:
main.c:7:10: warning: unused variable ‘is_valid’ [-Wunused-variable]
bool is_valid = isTrue();
^
/tmp/ccwIzgJQ.o: In function `main':
/home/paul/CS261/p1-check/mess/main.c:7: undefined reference to `isTrue'
collect2: error: ld returned 1 exit status
make: *** [main] Error 1
My Makefile was provided by my professor. I can post the contents here, but I'm confident it's correct. I know there's a linking error happening here, but why? I included the tester.h file in my main.c, so shouldn't isTrue be defined? Assistance would be greatly appreciated.
Edit: Here is the Makefile:
# Simple Makefile
#
#
# This makefile builds a simple application that contains a main module
# (specified by the EXE variable) and a predefined list of additional modules
# (specified by the MODS variable). If there are any external library
# dependencies (e.g., the math library, "-lm"), list them in the LIBS variable.
# If there are any precompiled object files, list them in the OBJS variable.
#
# By default, this makefile will build the project with debugging symbols and
# without optimization. To change this, edit or remove the "-g" and "-O0"
# options in CFLAGS and LDFLAGS accordingly.
#
# By default, this makefile build the application using the GNU C compiler,
# adhering to the C99 standard with all warnings enabled.
# application-specific settings and run target
EXE=y86
MODS=p1-check.o
OBJS=
LIBS=
default: $(EXE)
test: $(EXE)
make -C tests test
# compiler/linker settings
CC=gcc
CFLAGS=-g -O0 -Wall --std=c99 -pedantic
LDFLAGS=-g -O0
# build targets
$(EXE): main.o $(MODS) $(OBJS)
$(CC) $(LDFLAGS) -o $(EXE) $^ $(LIBS)
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -f $(EXE) main.o $(MODS)
make -C tests clean
.PHONY: default clean
Am I missing a part of the command when I try to use the Makefile for linking? It's probably something on my end, but I'm not sure what.
I figured out what I was doing wrong. I should have been saying make main.o when I wanted to link files with it. I wasn't paying enough attention to the build commands in Makefile, it seems. Thanks to kaylum for the clarification between declarations and definitions.

How to install/compile SDL2 C code on Linux/Ubuntu

I'm currently doing some C programming and I actually want to use the SDL library. I want to build a Small 2D game in C on Linux to sharp my skills a bit.
My issue is I'm not a super Makefile user nor library on Linux super user, I just configure things once when on a project and that's it.
So I have some trouble compiling SDL2 programs on UBUNTU 14.04.
I downloaded the latest SDL library from : http://www.libsdl.org/download-2.0.php
Then I installed it with the default step:
./configure
make
sudo make install
After that I can see that there is something in /usr/include/SDL2 so I guess it is installed.
#include <stdlib.h>
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char *argv[])
{
printf(“SDL test\n”);
return 0;
}
Because I'm still learning Makefiles and SDL I didn't figure it out to make it.
but I found this Makefile to compile the old SDL not the SDL2
CPP=gcc
CFLAGS=-O3
LDFLAGS=-lSDL -lSDL_mixer #Linker
EXEC=test
all: ${EXEC}
${EXEC}: ${EXEC}.o
${CPP} $(CFLAGS) -o ${EXEC} ${EXEC}.o ${LDFLAGS}
${EXEC}.o: ${EXEC}.c
${CPP} $(CFLAGS) -o ${EXEC}.o -c ${EXEC}.c
clean:
rm -fr *.o
mrproper: clean
rm -fr ${EXEC}
But this Makefile is not working for me it says that it doesn't know the lSDL_Mixer and other stuff.
How can I build a workable Makefile to compile C program with SDL2 using Makefiles and vim editor.
Thanks in advance for your help
I'll go ahead and clean up that Makefile for you.
CFLAGS = -O3
LDFLAGS =
appname = test
all: $(appname)
clean:
rm -f $(appname) *.o
.PHONY: all clean
sdl_cflags := $(shell pkg-config --cflags sdl2 SDL2_mixer)
sdl_libs := $(shell pkg-config --libs sdl2 SDL2_mixer)
override CFLAGS += $(sdl_cflags)
override LIBS += $(sdl_libs)
$(appname): test.o
$(CC) $(LDFLAGS) -o $# $^ $(LIBS)
Explanation
Variables in a makefile should be used with $(...), not ${...}.
pkg-config has an entry for SDL_Mixer, sdl-config does not. pkg-config is much more general.
using override with the SDL flags allows you to run something like make CFLAGS="-O0 -g" without breaking SDL support.
This is actually important: the SDL library flags have to be at the end of the command line, in LIBS, due to the fact that the GNU linker is sensitive to the order in which libraries are specified.
You don't need explicit rules for .c files, because GNU Make has implicit rules which are just fine.
Note that there are some very important features missing from this makefile. For example, it won't automatically recompile things when you change your header files. I would recommend that you use another build system, such as CMake or SCons, which handles this automatically. You can also do it with Make, but you'd have to paste several arcane lines of code into your makefile.
You can use sdl2-config as suggested by the SDL Linux FAQ to get the required compiler and linker flags:
SDL_CFLAGS := $(shell sdl2-config --cflags)
SDL_LDFLAGS := $(shell sdl2-config --libs)
CFLAGS := $(SDL_CFLAGS) -O3
LDFLAGS := $(SDL_LDFLAGS) -lSDL_mixer
It will find the location of your SDL.h and return the corresponding flag (e.g. -I/usr/include/SDL2 in your case) among other flags it deems necessary (e.g. for me it gives -D_THREAD_SAFE). And then you can simply #include <SDL.h>, which is the standard way to include SDL.

error in generating .ko file for simple hello world module for linux kernel

I am a beginner in linux kernel development and trying to load a simple module in linux.
I have created an hello.c file, to be loaded as kernel module.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
this hello.c and the makefile both, I have kept in /home/linux/ directory.
makefile
obj-m +=hello.o
src= /usr/src/linux-headers-3.5.0-17-generic
all:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
clean:
rm -rf *.o *.ko
to generate .ko file, when I run the make command on terminal from the /home/linux directory , I get following error
h2o#h2o-Vostro-1015:~/linux$ make
make -C /usr/src/linux-headers-3.5.0-17-generic SUBDIR-/home/h2o/linux modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
make[1]: *** No rule to make target `SUBDIR-/home/h2o/linux'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [all] Error 2
kindly advise what am I missing or doing wrong..
Makefile
obj-m := hello.o # Module Name is hello.c
KDIR := /lib/modules/$(shell uname -r)/build
all: $(MAKE) -C $(KDIR) M=$(PWD) modules
clean: $(MAKE) -C $(KDIR) M=$(PWD) clean $(RM) Module.markers
modules.order
its not guaranteed that headers file will always be located in /usr/src directory, but it will surely be located in /lib/modules directory.
make sure that system has latest header files
to find out which header files to be present
run `
uname -r
on terminal, output will be like
3.5.0-17-generic
to install header files run
sudo apt-get install linux-headers-$(uname -r)
You have:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
But it seems like you want:
$(MAKE) -C $(src)/SUBDIR-$(PWD) modules
Or something along those lines; where does the source code live? You need to -C there.
Kernel build system is a bit complex. It would be good to read the kernel build process documentation. Which gives better understanding about, say,
Targets like --- modules / modules_install
Options like --- -C $KDIR / M=$PWD
Command Syntax ---
$ make -C <path_to_kernel_src> M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD modules_install
Loadable module goals --- obj-m
etc...

Linking Opencv libraries in C

I've been attempting to write test a simple program using the opencv library. I have the following test code I found on a tutorial. I am running OSX 10.9.2 and managed (I think) to successfully install opencv on my computer using homebrew. My problem is that I cannot get this code to compile because my make file throws errors anytime I try to compile. I believe the issue is that I have not properly linked the libraries, and no amount of googling seems to have helped me solve my problem.
////////////////////////////////////////////////////////////////////////
//
// This is a simple, introductory OpenCV program. The program reads an
// image from a file, inverts it, and displays the result.
//
////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char** argv)
{
IplImage* img = cvLoadImage( "Conumdrum.jpeg", 0 ); //change the name (image.jpg) according to your Image filename.
cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
cvShowImage("Example1", img);
cvWaitKey(0);
cvReleaseImage( &img );
cvDestroyWindow( "Example1" );
return 0;
}
I found a sample makefile online that I've attempted to modify but to no avail, here is my makefile below:
# define the C compiler to use
CC = gcc
# define any compile-time flags
CFLAGS = -Wall -g
# define any directories containing header files other than /usr/include
#
INCLUDES = -I/Users/MY_NAME/Projects/Tank\ Game/Webcam_Tests/Webcam_Test_v1/include
# define library paths in addition to /usr/lib
# if I wanted to include libraries not in /usr/lib I'd specify
# their path using -Lpath, something like:
LFLAGS = -L/Users/MY_NAME/Projects/Tank\ Game/Webcam_Tests/Webcam_Test_v1/lib
# define any libraries to link into executable:
# if I want to link in libraries (libx.so or libx.a) I use the -llibname
# option, something like (this will link in libmylib.so and libm.so:
LIBS = -l libopencv_core.dylib -lm
# define the C source files
SRCS = Webcam_Test_v1.c
# define the C object files
#
# This uses Suffix Replacement within a macro:
# $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .c of all words in the macro SRCS
# with the .o suffix
#
OBJS = $(SRCS:.c=.o)
# define the executable file
MAIN = mycc
#
# The following part of the makefile is generic; it can be used to
# build any executable just by changing the definitions above and by
# deleting dependencies appended to the file from 'make depend'
#
.PHONY: depend clean
all: $(MAIN)
#echo Simple compiler named mycc has been compiled
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
# this is a suffix replacement rule for building .o's from .c's
# it uses automatic variables $<: the name of the prerequisite of
# the rule(a .c file) and $#: the name of the target of the rule (a .o file)
# (see the gnu make manual section about automatic variables)
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $#
clean:
$(RM) *.o *~ $(MAIN)
depend: $(SRCS)
makedepend $(INCLUDES) $^
# DO NOT DELETE THIS LINE -- make depend needs it
Terminal gives me the following output when I try to compile:
gcc -Wall -g -I/Users/MY_NAME/Projects/Tank\ Game/Webcam_Tests/Webcam_Test_v1/include -c Webcam_Test_v1.c -o Webcam_Test_v1.o
gcc -Wall -g -I/Users/MY_NAME/Projects/Tank\ Game/Webcam_Tests/Webcam_Test_v1/include -o mycc Webcam_Test_v1.o -L/Users/MY_NAME/Projects/Tank\ Game/Webcam_Tests/Webcam_Test_v1/lib -l libopencv_core.dylib -lm
ld: library not found for -llibopencv_core.dylib
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mycc] Error
Any help would be much appreciated, I've been beating my head against a wall for a couple of days now trying to solve this issue. It should also be noted that I am a novice, especially when it comes to makefiles. Thanks.
Your linker option is wrong. Try with -lopencv_core instead of -l libopencv_core.dylib.
For example, if you want to link a library which filename is libfoo.dylib, the right linker option is -lfoo.
And you will need to add -lopencv_highgui too.

Resources