openSuSE中的内核模块编程

 2010年02月23日 星期二 16时13分12秒
近几日一直在openSuSE上做内核模块编程。以前在fedora上写过一些例子,比较顺手。刚接触openSuSE,走了一些弯路,记录下来。
1、在安装openSuSE时,我在“开发”选择了“Linux内核开发”。所以,有了当前内核的源代码,和内核开发的一些文档。如果一开始没有选择,则要下载和当前内核版本一致的内核源代码(或者可以选择其他版本的源代码)。
2、我重新编译了内核源码,耗时数十分钟!
 cd /usr/src/linux-2.6.31.5-0.1/
 mkdir /home/sahu/build
 mkdir /home/sahu/build/kernel
 cp /boot/config-2.6.31.5-0.1-desktop .config
 make O=/home/sahu/build/kernel/ oldconfig
 make O=/home/sahu/build/kernel/
 sudo make O=/home/sahu/build/kernel/ modules_install
 sudo make O=/home/sahu/build/kernel/ install
这次编译内核,我参看了内核的README文件,将内核编译的结果放在一个自定义的目录中,而不是和内核源代码放在一起。
3、编写测试内核模块:dropAll.c,功能是丢弃所以网络数据包。
#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/skbuff.h>

#include <linux/ip.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

 

MODULE_LICENSE("GPL");

 

/* This is the structure we shall use to register our function */

    static struct nf_hook_ops nfho;

 

    /* This is the hook function itself */

    unsigned int hook_func(unsigned int hooknum,

                           struct sk_buff *skb,

                           const struct net_device *in,

                           const struct net_device *out,

                           int (*okfn)(struct sk_buff *))

    {

        return NF_DROP;           /* Drop ALL packets */

    }

 

    /* Initialisation routine */

    int init_module()

    {

        /* Fill in our hook structure */

        nfho.hook     = hook_func;         /* Handler function */

        nfho.hooknum  = NF_INET_PRE_ROUTING; /* First hook for IPv4 */

        nfho.pf       = PF_INET;

        nfho.priority = NF_IP_PRI_FIRST;   /* Make our function first */

 

        nf_register_hook(&nfho);

 

        pr_info("dropAll install into kernel!/n");

        return 0;

    }

            /* Cleanup routine */

    void cleanup_module()

    {

        nf_unregister_hook(&nfho);

        pr_info("dropAll removed from kernel!/n");

    }
4、编写Makefile文件,直接拷贝以前写的。
obj-m +=dropAll.o

all:

 make -C /usr/src/linux/ SUBDIRS=$(PWD) modules

clean:

 make -C /usr/src/linux M=$(PWD) clean

install:

 /sbin/insmod dropAll.ko

remove:

 /sbin/rmmod dropAll
编译时,各种错误!百思不得其解,偶然发现内核源码目录中有一个“Documentation/”目录,想必就是安装openSuSE时,“Linux内核开发”所带的文档,大喜!翻阅各个文档,发现有“kbuild/”目录,其中的modules.txt文件详细介绍了自定义内核模块的编译和安装等等。原来,上面的Makefile写法,是默认内核编译的输出目录是和内核源代码相同的。
于是将Makefile文件改为:
obj-m +=dropAll.o

all:

 make -C /lib/modules/`uname -r`/build M=`pwd`

clean:

 make -C /lib/modules/`uname -r`/build M=`pwd` clean

install:

 /sbin/insmod dropAll.ko

remove:

 /sbin/rmmod dropAll
没问题!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
欣喜之余,查看/lib/modules/2.6.31.5-0.1-desktop/,发现其中有个“build/”链接指向编译内核时自定义的输出目录:“/home/sahu/build/kernel
”;有“source/”链接指向内核源码目录:“/usr/src/linux-2.6.31.5-0.1”

因我安装了xen内核,于是重启机器到xen内核下,用上述Makefile编译,也没问题。查看/lib/modules/2.6.31.5-0.1-xen/,亦有build和source两个链接。只是build指向/usr/src/linux-2.6.31.5-0.1-obj/i386/xen,不同于前者。比较/usr/src/linux-2.6.31.5-0.1-obj/i386/xen和/home/sahu/build/kernel的大小,相当惊人7M Vs 3.5G!!

想想没重新编译内核之前,并没有/home/sahu/build/kernel,可见只是些编译的中间结果。于是重新建立链接:
 rm /lib/modules/2.6.31.5-0.1-desktop/build
 ln -s /usr/src/linux-2.6.31.5-0.1-obj/i386/desktop/ /lib/modules/2.6.31.5-0.1-desktop/build
删除/home/sahu/build/kernel
 rm -r /home/sahu/build/kernel
所以一开始,没有必要重新编译内核!是所以为“弯路”也!当然如果要安装新内核,则另当别论!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

5、编译此模块:

 make

6、安装模块

 

 make install

 

7、测试

 

 ping 127.0.0.1

 

可以发现,ping不通,哈哈!

 

8、卸载模块

 

 make remove

 

9、清理

 

 make clean

 

10、注意 :使用SSH登录目标机器的谨慎使用,因为连接会断开的!

你可能感兴趣的:(编程,struct,makefile,hook,linux内核,structure)