Benutzer-Werkzeuge

Webseiten-Werkzeuge


programming:kernel_module_26

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

programming:kernel_module_26 [2013/12/16 13:57] (aktuell)
idefix angelegt
Zeile 1: Zeile 1:
 +
 +====== ​ Kernel Module for 2.6  ======
 +=====  With Normal Makefile ​ =====
 +The hello world program. With normal Makefile, the Makefile:
 +<​code>​
 +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
 +</​code>​
 +
 +The hello_world.c:​
 +<​code>​
 +#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;​
 +}
 +</​code>​
 +
 +=====  With Automake and Autoconf ​ =====
 +
 +create the directory structure:
 +<​code>​
 +mkdir test
 +cd test
 +mkdir src
 +mkdir m4
 +touch NEWS
 +touch README
 +touch AUTHORS
 +touch ChangeLog
 +</​code>​
 +
 +Now we create the Makefile.am:​
 +<​code>​
 +ACLOCAL_AMFLAGS = -I m4
 +
 +SUBDIRS = src
 +EXTRA_DIST = autogen.sh
 +</​code>​
 +  *  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:​
 +<​code>​
 +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})
 +]
 +)
 +</​code>​
 +
 +Create now the file configure.ac:​
 +<​code>​
 +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)
 +</​code>​
 +  *  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:​
 +<​code>​
 +EXTRA_DIST = Makefile.kernel Makefile.common
 +EXTRA_PROGRAMS = automake_dummy
 +automake_dummy_SOURCES = hello_world.c
 +
 +module_DATA = hello_world.o
 +
 +include ./​Makefile.common
 +</​code>​
 +  *  "​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
 +    *  ...
 +
 +<​code>​
 +      Note: The user can specify the locations of these directories when running the configure script. For more info, run configure --help.</​code>​
 +
 +  *  "​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:​
 +<​code>​
 +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 ​
 +</​code>​
 +
 +Create Makefile.kernel:​
 +<​code>​
 +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
 +</​code>​
  
programming/kernel_module_26.txt · Zuletzt geändert: 2013/12/16 13:57 von idefix