www.nazgee.eu

  • projects
  • about me
  • igepv2
  • blog
Home › building a module against given kernel tree (makefile with crosscompiler selection)

Reply to comment

building a module against given kernel tree (makefile with crosscompiler selection)

nazgee — Thu, 04/22/2010 - 15:05

There are two ways to build a *.ko file for a specific kernel version. New module can be added directly to a kernel source tree, or it can be build outside it. There are pros and cons of both scenarios, so and deciding on a way to go is a matter of personal favour.

Building a module outside a kernel tree is straightforward- all it takes is to use a makefile like the one attached to this text. By editing content of the configuration section shown below you can alter:

  • path to the kernel sources that you'd like to finally insert your module to
  • cross compilation specifics, that is architecture and toolchain to use
  • name of the module

# ================ you probably want to modify variables below ==============

# .oOo. CONFIG VARIABLES

# Absoulte path to kernel, that this module is to be linked against
KERNEL_SRC_ABS_PATH = /workspace/oe/build/tmp-igep0020/work/igep0020-angstrom-linux-gnueabi/linux-igep2-2.6.28.10-0-r51/linux-omap-2.6.28.10-igep0020b-0
# Architecture and toolchain which should be used.
# Leave empty if not needed (native architectures module)
MAKE_FLAGS = ARCH=arm CROSS_COMPILE=/workspace/oe/build/tmp-igep0020/cross/armv7a/bin/arm-angstrom-linux-gnueabi-
# List of modules source files
C_SOURCE_FILES = src/hello_mod.c
# Desired name of the resulting .ko file
NAME_OF_THIS_MODULE = hello_module

Next section shown below is the real driver of this makefile. Its purpose might be obscure at the first glance, but in fact it is trivial.

# ============= you probably do NOT want to modify content below ============

# .oOo. HELPER VARIABLES

# generating list of object files
O_FILES = $(C_SOURCE_FILES:.c=.o)
# generating list of object files directiories
O_DIRS = $(dir $(O_FILES) )
# generating list of hidden o.cmd files
O_CMD_FILES = $(addsuffix .*.o.cmd, $(O_DIRS) )

# .oOo. KERNEL/MODULES BUILD SYSTEM

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
        obj-m := $(NAME_OF_THIS_MODULE).o
        $(NAME_OF_THIS_MODULE)-objs := $(O_FILES)
# Otherwise we were called directly from the command line; invoke the kernel
# build system. It will lead to calling this file again, but that time it
# will fall into opposite if-else case.  
else
        KERNELDIR ?= $(KERNEL_SRC_ABS_PATH)
        PWD := $(shell pwd)
all:
        $(MAKE) -C $(KERNELDIR) $(MAKE_FLAGS) M=$(PWD) modules
default: all
endif

distclean: clean
        rm -f $(O_FILES)
        rm -f $(O_CMD_FILES)  
        rm -f $(NAME_OF_THIS_MODULE)\.{ko,o,mod\.c,mod\.o}
        rm -f \.$(NAME_OF_THIS_MODULE)\.{ko\.cmd,o\.cmd,mod\.o\.cmd,}
        rm -f \.tmp_versions -r
clean:
        rm -f $(O_FILES)
        rm -f $(NAME_OF_THIS_MODULE)\.{ko,o,mod\.c,mod\.o}
        rm -f Module\.symvers modules\.order

The most important lines in this files look exactly the same as makefiles for all kernel modules look like. To be even more precise- these not only look as generic module's makefile, but are an exact copy of it. For those who are not familiar with kernel's build system, here it goes again:

obj-m := $(NAME_OF_THIS_MODULE).o
$(NAME_OF_THIS_MODULE)-objs := $(O_FILES)

Yes, that's it. It can be so simple because kernel uses nested makefiles, which helps to distribute complexity of the module's building task among hundreds of other files. Files at the bottom of this hierarchy can be very simple- as you can see, all that is needed is to specify a name and object files to be used.

What we'd like to achieve here, is to force kernel's build system to treat our makefile as one of it's own, and build a *.ko according to a recipe we embedded in it.

The thing is, that kernel's build system is not going to use our makefile if not explicitly told to do so- that is what rest of this makefile does. When make all is executed, it leads to invoking $(MAKE) -C $(KERNELDIR) $(MAKE_FLAGS) M=$(PWD) modules, which is when all the control is given away- the rest is up to kernel hackers. As a result our makefile is called for the second time- this time not from command line, but from kernel's build system, which is interested only in getting two lines described few paragraphs above.

As a result, *.ko file will be created in folder of our project. Copy it to your rootfs under development, and enjoy your new module.

Example of makefile and module's source code is attached.

AttachmentSize
hello_module.zip2.74 KB
‹ linux development up forcing Eclipse to work with Linux kernel (indexing kernel source) ›
  • C
  • howto
  • linux
  • tools
  • Add new comment
  • Polski Polski

Reply

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <embed> <object> <script>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <bash>, <c>, <cpp>, <diff>, <java>, <make>. The supported tag styles are: <foo>, [foo].
  • Images can be added to this post.
  • You may use [view:name=display=args] tags to display views.

More information about formatting options

  • English English
  • Polski Polski

Book navigation

  • IGEPv2
  • linux development
  • SPIN tutorials

Recent blog posts

  • Chester - the pink octopus
  • My first Android app
  • Online dictionary from command-line
  • mouse + servo = mouservo
  • Ubuntu One - maybe some time later
  • Setting up latest version of Eclipse under Ubuntu
more

Search

User login

  • Request new password

  • projects
  • about me
  • igepv2
  • blog

Copyright (C) nazgee Wszelkie prawa zastrzeżone