首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

第一个简单的内核编程实验:hello.c解决办法

2012-03-01 
第一个简单的内核编程实验:hello.c内核编程入门,就以最为简单的hello.c为例。环境:Redhat9.0,内核版本2.4.2

第一个简单的内核编程实验:hello.c
内核编程入门,就以最为简单的hello.c为例。
        环境:Redhat   9.0,内核版本2.4.20-8。
 
        虽然现在2.6.x的内核很早就就发布了,但是毕竟很多公司还在使用2.4.x的内核。作为新手,从2.4.x的内核入手是可行的。原因有如下几条:
        (1)2.4.x比较成熟。可能你遇到的绝大多数问题,网上都有解决方案。在这个过程中,你可以节省大量的时间,同时还可以对比网上的解决方案,加深认识,总结解决问题的方法,调整自己的学习方法和思路。
        (2)事物的发展总不可能是一蹴而就的。了解发展的历程,对深入理解问题有很大的好处。所以在2.4.x的内核的基础上学习2.6.x的内核,就能够体会到2.6.x的内核在哪些方面要出色,或者为什么要采取这种改进技术。相信理论清晰了,即时2.6.x的内核也会容易上手。
 
        下面总结了第一个内核程序hello.c的学习过程。
 
(一)第一阶段:尽量简单
 
/*
  *   hello.c
  */

#define   MODULE
#include   <linux/module.h>

int   init_module(void)
{
                printk( "Hello   World!\n ");
                return   0;
}

void   cleanup_module(void)
{
                printk( "Goodbye!\n ");
}
 

执行,出现错误一:

[root@lqm   drivers]#   gcc   -c   hello.c
[root@lqm   drivers]#   insmod   hello.o
hello.o:   kernel-module   version   mismatch
                hello.o   was   compiled   for   kernel   version   2.4.20
                while   this   kernel   is   version   2.4.20-8.
 

        这是因为内核源代码版本和编译器版本不一致造成的。

(1)编译器版本/usr/include/linux/version.h

#define   UTS_RELEASE   "2.4.20 "
#define   LINUX_VERSION_CODE   132116
#define   KERNEL_VERSION(a,b,c)   (((a)   < <   16)   +   ((b)   < <   8)   +   (c))
 

(2)内核源代码版本/usr/src/linux-2.4.20-8/include/linux/version.h

/usr/src/linux-2.4.20-8/include/linux
[root@lqm   linux]#   cat   version.h
#include   <linux/rhconfig.h>
#if   defined(__module__smp)
#define   UTS_RELEASE   "2.4.20-8smp "
#elif   defined(__module__BOOT)
#define   UTS_RELEASE   "2.4.20-8BOOT "
#elif   defined(__module__bigmem)
#define   UTS_RELEASE   "2.4.20-8bigmem "
#else
#define   UTS_RELEASE   "2.4.20-8 "
#endif
#define   LINUX_VERSION_CODE   132116
#define   KERNEL_VERSION(a,b,c)   (((a)   < <   16)   +   ((b)   < <   8)   +   (c))
 

      可以采取修改编译器版本号与内核源代码版本号一致的办法来解决这个问题,即修改/usr/include/linux/version.h中   #define   UTS_RELEASE   "2.4.20 "
 


为   #define   UTS_RELEASE   "2.4.20-8 "
 


执行,出现错误二:

[root@lqm   drivers]#   gcc   -c   hello.c
[root@lqm   drivers]#   insmod   hello.o
Warning:   loading   hello.o   will   taint   the   kernel:   no   license
    See   http://www.tux.org/lkml/#export-tainted   for   information   about   tainted   modules
Module   hello   loaded,   with   warnings
[root@lqm   drivers]#   tail   -n   1   /var/log/messages
Jan   30   12:02:08   lqm   kernel:   Hello  


 

          也就是说出现了no   license的警告。GNU的软件需要有GPL,所以修改源代码如下:

/*
  *   hello.c
  */

#define   MODULE
#include   <linux/module.h>

MODULE_LICENSE( "GPL ");

int   init_module(void)
{
                printk( "Hello   World!\n ");
                return   0;
}

void   cleanup_module(void)
{
                printk( "Goodbye!\n ");
}
 

        这时没有错误了。写了一个脚本,测试流程自动化:

#!/bin/bash

gcc   -c   hello.c
sleep   1

insmod   hello.o   &&   echo   -e   "Instal   module   -   hello.o\n "
sleep   1
tail   -n   1   /var/log/messages
lsmod   |   grep   "hello "   &&   echo   -e   "Module   hello   has   instaled\n "

rmmod   hello   &&   echo   -e   "Remove   module   -   hello\n "
sleep   1
tail   -n   1   /var/log/messages
lsmod   |   grep   "hello "   ||   echo   "Module   hello   has   removed "
 

执行结果如下:

[root@lqm   hello]#   ./run

Instal   module   -   hello.o  

Jan   30   13:31:29   lqm   kernel:   Hello   World!  

hello   748   0   (unused)  

Module   hello   has   instaled  

Remove   module   -   hello  

Jan   30   13:31:30   lqm   kernel:   Goodbye!  

Module   hello   has   removed
 

(二)第二阶段:完善,深入一点

/*
  *   hello.c
  */

#ifndef   __KERNEL__
                #define   __KERNEL__
#endif
#ifndef   MODULE
                #define   MODULE
#endif

#include   <linux/kernel.h>   /*printk*/
#include   <linux/module.h>

MODULE_LICENSE( "GPL ");

static   int   init_module(void)
{
                printk( "Hello,   world!\n ");

                return   0;
}

static   void   cleanup_module(void)
{
                printk( "Goodbye!\n ");
}
 

写Makefile文件如下:

#   Kernel   Programming
#   Shandong   University,   Linqingmin

#   The   path   of   kernel   source   code
INCLUDEDIR   =   /usr/src/linux-2.4.20-8/include/

#   Compiler
CC   =   gcc

#   Options
CFLAGS   =   -D__KERNEL__   -DMODULE   -O   -Wall   -I$(INCLUDEDIR)

#   Target
OBJS   =   hello.o

all:   $(OBJS)

$(OBJS):   hello.c   /usr/include/linux/version.h
                $(CC)   $(CFLAGS)   -c   $ <



install:
                insmod   $(OBJS)

uninstall:
                rmmod   hello

.PHONY:   clean
clean:
                rm   -f   *.o
 

        写Makefile时应该注意,不要用空格来代替 <TAB> 。否则会出现错误:missing   separator.   Stop.

修改执行脚本run:

#!/bin/bash

#   The   first   step
make   &&   make   install   &&   echo   -e   "Instal   module   -   hello.o\n "
sleep   1
tail   -n   1   /var/log/messages
lsmod   |   grep   "hello "   &&   echo   -e   "Module   hello   has   instaled\n "

#   The   second   step
make   uninstall   &&   echo   -e   "Remove   module   -   hello\n "
sleep   1
tail   -n   1   /var/log/messages
lsmod   |   grep   "hello "   ||   echo   "Module   hello   has   removed "

#   The   last   step
make   clean
 

执行结果如下:

[root@lqm   hello]#   ./run
gcc   -D__KERNEL__   -DMODULE   -O   -Wall   -I/usr/src/linux-2.4.20-8/include/   -c   hello.c
hello.c:18:   warning:   `init_module '   defined   but   not   used
hello.c:25:   warning:   `cleanup_module '   defined   but   not   used
insmod   hello.o
Instal   module   -   hello.o

Jan   31   13:40:23   lqm   kernel:   Hello,  
hello   728   0   (unused)
Module   hello   has   instaled

rmmod   hello
Remove   module   -   hello

Jan   31   13:40:24   lqm   kernel:  
Module   hello   has   removed
rm   -f   *.o
 



[解决办法]
顶一把,对于初学者还是有不少帮助的。
[解决办法]
顶一个,最近也在看这方面的东西 .
[解决办法]
ding

[解决办法]
good
[解决办法]
标记,收藏下
[解决办法]
mark
[解决办法]
mark
[解决办法]
mark
[解决办法]
收藏
[解决办法]
good
[解决办法]
不错,2.4与2.6还是有较大的区别的
[解决办法]
我也正学呢,谢谢
[解决办法]
mark
------解决方案--------------------


Good!
[解决办法]
好东西,谢谢!
[解决办法]
记号````
[解决办法]
good
[解决办法]
2.6的内核做得有点太模块化了
[解决办法]
mark

热点排行