programming:kernel_module_26
Inhaltsverzeichnis
Kernel Module for 2.6
With Normal Makefile
The hello world program. With normal Makefile, the Makefile:
ARCH := i386 CROSS_COMPILE := #CROSS_COMPILE := ppc_6xxx- INSTALL := install -c INSTALL_DATA := $(INSTALL) -m 644 KERNELVERSION := $(shell uname -r) # KERNELVERSION := 2.6.16-mpc52xx-gc92bc8e3 EXTRA_CFLAGS := -g -I/usr/realtime/include -I/usr/include/ -ffast-math -mhard-float KDIR := /lib/modules/$(KERNELVERSION)/build PWD := $(shell pwd) obj-m := hello_world.o all: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) # gcc -o scope scope.c clean: rm -f *.o *.ko *.mod.o *.mod.c .*.{cmd,flags} Modules.symvers rm -rf config.status config.log autom4te*.cache .tmp_versions
The hello_world.c:
#include <linux/module.h> #include <asm/io.h> #include <rtai.h> #include <rtai_sched.h> #include <rtai_fifos.h> MODULE_LICENSE("GPL"); int init_module(void) { printk("in init_module\n"); return 0; } void cleanup_module(void) { printk("in cleanup_module\n"); return; }
With Automake and Autoconf
create the directory structure:
mkdir test cd test mkdir src mkdir m4 touch NEWS touch README touch AUTHORS touch ChangeLog
Now we create the Makefile.am:
ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src EXTRA_DIST = autogen.sh
- ACLOCAL_AMFLAGS says aclocal where to look for additional m4 macros
- SUBDIRS are processed
- EXTRA_DIST says to include the autogen.sh in our distribution tar
Now we create a m4 script to get the kernel-source named m4/acinclude.m4:
dnl check for kernel source AC_DEFUN([AC_PATH_KERNEL_SOURCE_SEARCH], [ kerneldir=missing kernelext=ko no_kernel=yes if test `uname` != "Linux"; then kerneldir="not running Linux" else for dir in /usr/src/kernel-source-`uname -r` /usr/src/linux-`uname -r` /usr/src/linux /lib/modules/`uname -r`/build ${ac_kerneldir}; do if test -d $dir; then kerneldir=`dirname $dir/Makefile`/ no_kernel=no fi; done fi if test x${no_kernel} != xyes; then if test -f ${kerneldir}/Makefile; then if test "${ac_pkss_mktemp}" = "yes"; then ac_pkss_makefile=`mktemp /tmp/LIRCMF.XXXXXX` else ac_pkss_makefile=/tmp/LIRCMF.XXXXXX fi cat ${kerneldir}/Makefile >${ac_pkss_makefile} echo "lirc_tell_me_what_cc_is:" >>${ac_pkss_makefile} echo " echo \$(CC)" >>${ac_pkss_makefile} kernelcc=`make -s -C ${kerneldir} -f ${ac_pkss_makefile} lirc_tell_me_what_cc_is` echo "lirc_tell_me_what_version_is:" >>${ac_pkss_makefile} echo " echo \$(VERSION)" >>${ac_pkss_makefile} echo "lirc_tell_me_what_patchlevel_is:" >>${ac_pkss_makefile} echo " echo \$(PATCHLEVEL)" >>${ac_pkss_makefile} version=`make -s -C ${kerneldir} -f ${ac_pkss_makefile} lirc_tell_me_what_version_is` patchlevel=`make -s -C ${kerneldir} -f ${ac_pkss_makefile} lirc_tell_me_what_patchlevel_is` if test ${version} -eq 2; then if test ${patchlevel} -lt 5; then kernelext=o fi fi rm -f ${ac_pkss_makefile} else kerneldir="no Makefile found" no_kernel=yes fi fi ac_cv_have_kernel="no_kernel=${no_kernel} \ kerneldir=\"${kerneldir}\" \ kernelext=\"${kernelext}\" \ kernelcc=\"${kernelcc}\"" ] ) AC_DEFUN([AC_PATH_KERNEL_SOURCE], [ AC_CHECK_PROG(ac_pkss_mktemp,mktemp,yes,no) AC_PROVIDE([AC_PATH_KERNEL_SOURCE]) AC_MSG_CHECKING(for Linux kernel sources) AC_ARG_WITH(kerneldir, [ --with-kerneldir=DIR kernel sources in DIR], ac_kerneldir=${withval} AC_PATH_KERNEL_SOURCE_SEARCH, ac_kerneldir="" AC_CACHE_VAL(ac_cv_have_kernel,AC_PATH_KERNEL_SOURCE_SEARCH) ) eval "$ac_cv_have_kernel" AC_SUBST(kerneldir) AC_SUBST(kernelcc) AC_SUBST(kernelext) AC_MSG_RESULT(${kerneldir}) ] )
Create now the file configure.ac:
dnl Proccess this file with autoconf to produce a configure script. AC_INIT(hello_world, 0.1) AC_PREREQ(2.5) AC_CONFIG_SRCDIR(src/hello_world.c) AC_CONFIG_AUX_DIR(config) AM_INIT_AUTOMAKE(1.8) dnl Checks for programms AC_PROG_CC AC_PATH_KERNEL_SOURCE default_moduledir=/lib/modules/`uname -r`/misc AC_ARG_WITH(moduledir, [ --with-moduledir=DIR kernel modules in DIR (/lib/modules/`uname -r`/misc)], moduledir=${withval}, moduledir=${default_moduledir}) AC_SUBST(moduledir) AC_OUTPUT(Makefile src/Makefile)
- AC_INIT init the file with project name, version and email address
- AC_CONFIG_AUX_DIR says autoconf to store tmp file in the dir config to keep the main dir clean
- AC_CONFIG_SRCDIR where is the program to compile
- AM_INIT_AUTOMAKE directive to generate the Makefile
- AC_PROC_CC check for gcc
- AC_OUTPUT generate the following files from the *.in or *.am files
Now generate the src/Makefile.am:
EXTRA_DIST = Makefile.kernel Makefile.common EXTRA_PROGRAMS = automake_dummy automake_dummy_SOURCES = hello_world.c module_DATA = hello_world.o include ./Makefile.common
- „PROGRAMS“ is called a primary. Other primaries include:
- LIBRARIES for static libraries (.a)
- LTLIBRARIES for Libtool-based shared libraries (.la)
- HEADERS
- …
- The prefix „bin_“ tells Automake where to copy the resulting program when the user runs make install. Known directory prefixes include:
- bin_ - for programs, e.g., /usr/local/bin
- lib_ - where libraries are placed, e.g., /usr/local/lib
- include_ - where header files are placed, e.g., /usr/local/include
- pkginclude_ - e.g., /usr/local/include/foobar
- noinst_ - files that will not be copied anywhere by make install
- …
Note: The user can specify the locations of these directories when running the configure script. For more info, run configure --help.
- „SOURCES“ is a variable that lists the source files of the program. For programs and libraries, possible variables include:
- CFLAGS, CPPFLAGS, CXXFLAGS - extra arguments passed to the compiler/preprocessor
- LIBADD - extra objects for a library
- LDADD - extra objects for a program
- LDFLAGS - extra arguments passed to the linker
- …
Create the Makefile.common:
KERNEL_LOCATION=@kerneldir@ KBUILD_VERBOSE = 1 ARCH := i386 CROSS_COMPILE := #CROSS_COMPILE := ppc_6xxx- #KERNELVERSION := $(shell uname -r) # KERNELVERSION := 2.6.16-mpc52xx-gc92bc8e3 HELLO_WORLD_EXTRA_CFLAGS = -g -I/usr/realtime/include -I/usr/include/ -ffast-math -mhard-float PWD := $(shell pwd) export HELLO_WORLD_EXTRA_CFLAGS module_DATA $(module_DATA): $(automake_dummy_SOURCES) mv Makefile Makefile.automake cp Makefile.kernel Makefile $(MAKE) -C $(KERNEL_LOCATION) SUBDIRS=$(PWD) modules \ KBUILD_VERBOSE=$(KBUILD_VERBOSE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) mv Makefile.automake Makefile CLEANFILES = $(module_DATA) .$(module_DATA).{cmd,flags} .$(module_DATA:.o=.@kernelext@).cmd \ $(module_DATA:.o=.mod.c) .$(module_DATA:.o=.mod.o.cmd) $(module_DATA:.o=.@kernelext@) \ Modules.symvers *~ clean: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) rm -rf .tmp_versions
Create Makefile.kernel:
EXTRA_CFLAGS += $(HELLO_WORLD_EXTRA_CFLAGS) obj-m=$(module_DATA) MI_OBJS = $(module_DATA) all clean: $(warning **************************************************) $(warning *** Makefile trick not undone, trying to recover *) $(warning **************************************************) mv Makefile.automake Makefile $(MAKE) $@ # The following is needed for 2.5 kernels and also let's the makefile work # when things get screwed. ifneq (,$(wildcard $(KERNEL_LOCATION)/Rules.make)) include $(KERNEL_LOCATION)/Rules.make endif
programming/kernel_module_26.txt · Zuletzt geändert: 2013/12/16 13:57 von idefix