LKM Makefile, extract source files from source directories - linux

I have the following project structure for a simple kernel module and I want to be able to build this by extracting the source files from the provided source directories in the Makefile.
Makefile
src/
main.c
sub_src/
sub_src.c
sub_src.h
I will describe my issue soon but I will first provide the code.
main.c :
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include "sub_src/sub_src.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Unknown");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
sub_src_printk("sub_src.c\n");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
sub_src.h :
#ifndef __SUB_SRC_H___
#define __SUB_SRC_H___
#include <linux/kernel.h> // included for KERN_INFO
void sub_src_printk( const char* );
#endif /* __SUB_SRC_H___ */
sub_src.c :
#include "sub_src.h"
void sub_src_printk( const char* msg )
{
printk(KERN_INFO "%s", msg);
}
Makefile :
MODULE_NAME ?= test_module
TEST ?= 0
INCLUDE_DIRS = -I$(src)/src/sub_src
ccflags-y := $(INCLUDE_DIRS)
ifeq ($(TEST), 1)
SRC_DIRS := \
src \
src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src_dir)/*.c))
else
SRCS := \
src/main.c \
src/sub_src/sub_src.c
endif
#extract required object files
OBJ_SRCS := $(SRCS:.c=.o)
#setup kbuild
obj-m += $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
all:
#echo ""
#echo "------- Building the LKM ($(MODULE_NAME).ko) -------"
#echo "INCLUDE_DIRS = $(INCLUDE_DIRS)"
#echo "SRCS = $(SRCS)"
#echo "OBJS_SRCS = $(OBJ_SRCS)"
#echo "ccflags-y = $(ccflags-y)"
#echo "obj-m = $(obj-m)"
#echo "test_module-y = $(test_module-y)"
#echo "-----------------------------------------------------"
#echo ""
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
The idea is that I should be able to build this module by providing only the source directories in the Makefile by calling make as:
make all TEST=1
But I have the option (for now) to provide the path to the source files by calling make as following:
make all TEST=0
These two calls should ideally provide the same result i.e a functional kernel module ready to be inserted (via sudo insmod ...). This is however not the case. (make all TEST=0 works as intended while make all TEST=1 does not)
make all TEST=0 gives the following output: (make clean has been called before this command)
------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------
make -C /lib/modules/3.19.0-59-generic/build M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
CC [M] /home/henrik/Desktop/test_lkm_dev/new_test/src/main.o
CC [M] /home/henrik/Desktop/test_lkm_dev/new_test/src/sub_src/sub_src.o
LD [M] /home/henrik/Desktop/test_lkm_dev/new_test/test_module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/henrik/Desktop/test_lkm_dev/new_test/test_module.mod.o
LD [M] /home/henrik/Desktop/test_lkm_dev/new_test/test_module.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'
make all TEST=1 gives the following output: (make clean has been called before this command)
------- Building the LKM (test_module.ko) -------
INCLUDE_DIRS = -I/src/sub_src
SRCS = src/main.c src/sub_src/sub_src.c
OBJS_SRCS = src/main.o src/sub_src/sub_src.o
ccflags-y = -I/src/sub_src
obj-m = test_module.o
test_module-y = src/main.o src/sub_src/sub_src.o
-----------------------------------------------------
make -C /lib/modules/3.19.0-59-generic/build M=/home/henrik/Desktop/test_lkm_dev/new_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-59-generic'
make[2]: *** No rule to make target `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.c', needed by `/home/henrik/Desktop/test_lkm_dev/new_test/test_module.o'. Stop.
make[1]: *** [_module_/home/henrik/Desktop/test_lkm_dev/new_test] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-59-generic'
make: *** [all] Error 2
The debugging info shows (as far I can see) that the variables in the Makefile contains the same values with the different approaches.
But the second alternative (TEST=1) somehow have the impression that there should be a source file called test_module.c which isn't the case.
Do someone/anyone have an idea why this happens and how I can solve it? (I have been pulling my hair out for the last two hours..)
Solution (The Makefile):
MODULE_NAME ?= test_module
TEST ?= 0
INCLUDE_DIRS = -I$(src)/src/sub_src
ccflags-y := $(INCLUDE_DIRS)
ifeq ($(TEST), 1)
# Paths to source directories
SRC_DIRS := \
src \
src/sub_src
SRCS := $(foreach src_dir,$(SRC_DIRS),$(wildcard $(src)/$(src_dir)/*.c))
SRCS := $(SRCS:$(src)/%=%)
else
SRCS := \
src/main.c \
src/sub_src/sub_src.c
endif
# extract required object files
OBJ_SRCS := $(SRCS:.c=.o)
# setup kbuild
obj-m := $(MODULE_NAME).o
$(MODULE_NAME)-y := $(OBJ_SRCS)
$(MAKE) = make
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
all:
#echo ""
#echo "------- Building the LKM ($(MODULE_NAME).ko) -------"
ifeq ($(TEST), 1)
#echo "Compiling with TEST = 1"
else
#echo "Compiling with TEST = 0"
endif
#echo ""
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
Many thanks!
Henrik

Related

Wii Homebrew Development... FT_Library and FT_Face not declared

I have followed a tutorial on Wii Homebrew Development for displaying better fonts. And there seems to be some issues with the library I am using. FT_Library and FT_Face are not declared. The library I am using is ftImage, do I have to setup FT_Library? If so how is it done on Windows?
My makefile
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
DATA := data
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $#).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwiiuse -lbte -logc -lm -lfreetype -lftimage
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
#[ -d $# ] || mkdir -p $#
#$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
#echo clean ...
#rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
wiiload $(TARGET).dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
$(OFILES_SOURCES) : $(HFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o %_jpg.h : %.jpg
#---------------------------------------------------------------------------------
#echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .ttf extension
#---------------------------------------------------------------------------------
%.ttf.o : %.ttf
#---------------------------------------------------------------------------------
#echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
My main code (From tutorial)
#include <stdio.h>
#include <stdlib.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
#include <iostream>
#include "libs/ftImage.h" //The ftimage library
#include "fontawesome_webfont_ttf.h"
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
//---------------------------------------------------------------------------------
int main(int argc, char **argv) {
//---------------------------------------------------------------------------------
// Initialise the video system
VIDEO_Init();
// This function initialises the attached controllers
WPAD_Init();
// Obtain the preferred video mode from the system
// This will correspond to the settings in the Wii menu
rmode = VIDEO_GetPreferredMode(NULL);
// Allocate memory for the display in the uncached region
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
// Initialise the console, required for printf
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
// Set up the video registers with the chosen mode
VIDEO_Configure(rmode);
// Tell the video hardware where our display memory is
VIDEO_SetNextFramebuffer(xfb);
// Make the display visible
VIDEO_SetBlack(FALSE);
// Flush the video register changes to the hardware
VIDEO_Flush();
// Wait for Video setup to complete
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
// The console understands VT terminal escape codes
// This positions the cursor on row 2, column 0
// we can use variables for this with format codes too
// e.g. printf ("\x1b[%d;%dH", row, column );
ftImage print(640, 480); //This will store the string of text we print
Sprite Text; //This Sprite will be used to render the ftImage member print
print.setFont(fontawesome_webfont_ttf, fontawesome_webfont_ttf_size);//Set the font we are using
print.setSize(32);//Set the size of the font (should be a multiple of 4)
print.setColor(Color(255,40,40));//Set the color of the font in RGB format
Text.SetPosition(100, 50);//Set the position of the starting point of the text we will print
Text.SetImage(&print);//Append print as the image stored by Text
print.printf(" Hellow World!\n");//Set the string of text to be rendered (escape characters can be use to render more than one line)
print.flush();//Tell the computer that the string of text is ready
Text.Draw();//Render the text
print.clear();//Clear the stored string of text
print.reset();//Bring us back to the render starting point (defined by Text.SetPosisition())
while(1) {
// Call WPAD_ScanPads each loop, this reads the latest controller states
WPAD_ScanPads();
// WPAD_ButtonsDown tells us which buttons were pressed in this loop
// this is a "one shot" state which will not fire again until the button has been released
u32 pressed = WPAD_ButtonsDown(0);
// We return to the launcher application via exit
if ( pressed & WPAD_BUTTON_HOME ) exit(0);
// Wait for the next frame
VIDEO_WaitVSync();
}
return 0;
}
I dont think I can post the library code legally so I will say the library name
ftImage

Trouble with hello world linux kernel module makefile

I have this code for the hello world module :
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO "Hello module\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Bye module\n");
}
Makefile :
obj-m := hello.o
K := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(K) M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I get this compile message from the makefile :
make -C /lib/modules/3.16.0-4-amd64/build M=/home/neo/ker modules
make[1]: Entering directory '/usr/src/linux-headers-3.16.0-4-amd64'
Makefile:10: *** mixed implicit and normal rules: deprecated syntax
make[1]: Entering directory `/usr/src/linux-headers-3.16.0-4-amd64'
CC [M] /home/neo/ker/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/neo/ker/hello.mod.o
LD [M] /home/neo/ker/hello.ko
make[1]: Leaving directory '/usr/src/linux-headers-3.16.0-4-amd64'
this is the warning that i don't understand:
Makefile:10: *** mixed implicit and normal rules: deprecated syntax
Thanks in advance

How to include SDL in your program (Linux). undefined reference to SDL_Init()

Im trying everything to run this test Program and keep getting this error messages:
g++ objects/src_files/display.o objects/src_files/main.o -o program -L/usr/local/lib
objects/src_files/main.o: In function `main':
main.cpp:(.text+0x16): undefined reference to `SDL_Init'
collect2: error: ld returned 1 exit status
make: *** [program] Error 1
this is how my test program looks like:
#include <iostream>
#include <string>
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <glm/glm.hpp>
#include <display.hpp>
using namespace std;
int main(int argc, char **argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
glm::vec3 my_v(0, 0, 0);
string s = "This is a Test";
cout << s << endl;
return 0;
}
and this is my MAKEFILE:
APP = program
CC = g++
SRCDIR = src_files
OBJDIR = objects
H_DIR = header_files
INC_DIR = include
LIB_DIR = /usr/local/lib
SRCS := $(shell find $(SRCDIR) -name '*.cpp')
SRCDIRS := $(shell find . -name '*.cpp' -exec dirname {} \; | uniq)
OBJS := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SRCS))
CFLAGS = -Wall -pedantic -ansi -lSDL
LDFLAGS =
#update here
_H = $(HD_DIR)/display.hpp
SDL_H = $(INC_DIR)/SDL.h
MAIN_H = $(_H) $(SDL_H)
all: $(APP)
$(APP) : buildrepo $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $#
$(OBJDIR)/%.o: %.cpp
$(CC) $(CFLAGS) -I$(INC_DIR) -I$(H_DIR) -c $< -o $#
#update here
$(OBJ_DIR)/main.o: $(MAIN_H)
$(OBJ_DIR)/display.o: $(_H) $(SDL_H)
clean:
$(RM) $(OBJS)
distclean: clean
$(RM) $(APP)
buildrepo:
#$(call make-repo)
define make-repo
for dir in $(SRCDIRS); \
do \
mkdir -p $(OBJDIR)/$$dir; \
done
endef
I run the MAKEFILE with: make -f MAKEFILE
What else can I try?
Thanks
In your Makefile change
CFLAGS = -Wall -pedantic -ansi -lSDL
LDFLAGS =
To
CFLAGS = -Wall -pedantic -ansi
LDFLAGS = -lSDL
-lSDL is actually a linker flag, not compiler.

Module verification failed when insmod a module

On Ubuntu 14.04, Kernel 3.13.0, When I insert below simple module, I got error message from kernel log:
"module verification failed: signature and/or required key missing - tainting kernel"
Did I made any mistake or missed anything?
Here is module source code in a file named ts2.c.
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_ALIAS("hello2");
static int __init hello1_init(void)
{
printk(KERN_INFO "Hello world 2.\n");
return 0;
}
static void __exit hello1_exit(void)
{
printk(KERN_INFO "Goodbye world 2.\n");
}
module_init(hello1_init);
module_exit(hello1_exit);
Here is the Makefile:
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := ts2.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD) clean
endif
depend .depend dep:
$(CC) $(EXTRA_CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
You have a problem in your make file...
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := ts2.o
Rather it should be as below:
ifeq ($(DEBUG),y)
DEBFLAGS = -O -g -DPCI_INFO_DEBUG # "-O" is needed to expand inlines
else
DEBFLAGS = -O2
endif
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
ifneq ($(KERNELRELEASE),)
obj-m := hello1.o
Now your issues should be solved

make: -c: Command not found

First of all, I'm trying to get used to makefiles but yet I#m new with this. The following file is supposed to, first, compile all ./src/*.cpp files to ./src/*.o (where the filename survives) and afterwards complete compilation with simulation.cpp and linking the whole stuff together. Now, make returns the error message:
make: -c: Command not found
I have literally no clue how to proceed! Would the wildcard-construct even work in the way desired? Thanks a lot for your effort!
#basic stuff
TRUE = 1
FALSE = 0
SHELL := #!/bin/bash
# path names
SRCPATH = ./src/
CLEANPATH = ./res/ \
./crash/
# source files.
MAIN = simulation.cpp
OBJS = $(wildcard $(SRCPATH)*.o)
SRCS = $(wildcard $(SRCPATH)*.cpp)
INCLUDES = $(wildcard $(SRCPATH)*.h)
#GLOBAL MACROS PASSED TO PROGRAM!
MODEL_MRT = $(TRUE) #if true model used is MRT else SRT
PARALLEL = $(TRUE)
GRAVITY = $(TRUE)
# output file name
OUT = simulation
# C++ compiler flags (-g -O2 -Wall)
CXXFLAGS = -g -Wall -O -fopenmp
CXXDEFINES = -D MODEL=$(MODEL_MRT) -D PARALLEL=$(PARALLEL) -D GRAVITY=$(GRAVITY)
# compiler
CXX = g++
$(OUT) : $(OBJS)
$(CXX) $(CXXFLAGS) $(MAIN) $(OBJS) $(CXXDEFINES) -o $(OUT)
$(OBJS) : $(SRCS) $(INCLUDES)
$(CXX) $(CXXFLAGS) -c $(SRCS) -o $(OBJS)
clean : $(OUT)
rm $(OBJS)
rm $(CLEANPATH)/*.*
run : $(OUT) clean
./$(OUT)
.PHONY: clean run
You're tricking make with your SHELL variable, it sees is at empty as it is just a comment.
Change
SHELL := #!/bin/bash
to
SHELL := /bin/bash
This line:
SHELL := #!/bin/bash
is incorrect.
Your makefile should work perfectly well if you leave that line out altogether. If you do need something there, try
SHELL := /bin/bash

Resources