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