您的位置:首页 > 运维架构 > Linux

Linux内核模块开发实例学习

2017-09-14 09:09 302 查看
 注:以下程序只是在我机器上测试通过,但代码不一定合理或高效,只是想了解一下内核模块的开发流程,以及工作流程
例子来源于网络,在此表示感谢

[cpp] view
plain copy

[root@localhost module]# cat /proc/version   

Linux version 2.6.18-194.el5xen (mockbuild@builder16.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)) #1 SMP Fri Apr 2 16:16:54 EDT 2010  

1、编写最简单的helloworld版本的内核模块

[cpp] view
plain copy

[root@localhost module]# cat hello.c   

#ifndef _KERNEL_  

        #define _KERNEL_  

#endif  

  

#ifndef MODULE  

        #define MODULE  

#endif  

  

  

#include <linux/config.h>  

#include <linux/module.h>  

#include <linux/kernel.h>  

  

static int hello_init(void)  

{  

        printk(KERN_ALERT "hello, I am Tuotuo\n");  

        return 0;  

}  

  

static void hello_exit(void)  

{  

        printk(KERN_ALERT "googbye Kernel mymodule n");  

}  

  

module_init(hello_init);  

module_exit(hello_exit);  

Makefile文件为

[cpp] view
plain copy

[root@localhost module]# cat Makefile   

obj-m:=hello.o   

VERSION_NUM:=$(shell uname -r)  

KERNELBUILD := /lib/modules/`uname -r`/build  

CURRENT_PATH:=$(shell pwd)  

  

all:  

        make -C $(KERNELBUILD) M=$(CURRENT_PATH) modules  

  

clean:  

        make -C $(KERNELBUILD) M=$(CURRENT_PATH) clean  

编译
make
加载模块
insmod hello.ko
卸载模块

[cpp] view
plain copy

rmmod hello.ko   

查看加载和卸载信息
dmesg
2、学习调用模块
学习http://blog.csdn.net/firststp/article/details/395009

内核模块代码

[cpp] view
plain copy

[root@localhost module]# cat TestModule.c   

#ifndef _KERNEL_  

        #define _KERNEL_  

#endif  

  

#ifndef MODULE  

        #define MODULE  

#endif  

  

  

#include <linux/config.h>  

#include <linux/module.h>  

#include <linux/kernel.h>  

#include <linux/version.h>  

#include <linux/types.h>  

#include <linux/fs.h>  

#include <linux/mm.h>  

#include <linux/errno.h>  

#include <asm/segment.h>  

#include <linux/sched.h>  

#include <asm/uaccess.h>  

#include <linux/utsrelease.h>  

  

#define DATA_LENGTH 10  

  

MODULE_LICENSE("GPL");  

MODULE_AUTHOR("TUO LI HENG");  

  

char kernel_version[] = UTS_RELEASE;  

  

unsigned int test_major = 0;  

  

ssize_t read_test(struct file *file, char * buf, size_t count, loff_t *f_ops)  

{  

        int left, i, *p;  

        int data[DATA_LENGTH];  

        p = data;  

        for(i=0; i<10; ++i)  

                data[i] = 61;  

  

        for(left=count; left>0; --left)  

        {  

                copy_to_user(buf, p, 1);  

                ++buf;  

                ++p;  

        }  

        return 0;  

  

}  

  

ssize_t write_test(struct file *file, char * buf, size_t count, loff_t *f_ops)  

{  

  

        return 0;  

}  

  

static int open_test(struct inode* inode, struct file *file)  

{  

        //      MOD_INC_USE_COUNT;  

        return 0;  

  

}  

  

static int release_test(struct inode *inode, struct file *file)  

{  

        //      MOD_DEC_USE_COUNT;  

        return 0;  

}  

  

struct file_operations test_fops = {  

read: read_test,  

write: write_test,  

open: open_test,  

release: release_test  

  

};  

  

  

static int hello_init(void)  

{  

        printk(KERN_ALERT "hello, I am Tuotuo\n");  

        int result = 0;  

        result = register_chrdev (0, "test", &test_fops);  

        if(result < 0)  

        {  

                printk(KERN_ALERT "test:can't get major number\n");  

                return result;  

        }  

        if(test_major == 0)  

                test_major = result;  

        printk(KERN_ALERT "test major:%d/r/n", result);  

        return 0;  

}  

  

  

static void hello_exit(void)  

{  

        unregister_chrdev(test_major, "test");  

        printk(KERN_ALERT "googbye Kernel module tuotuo\n");  

}  

  

module_init(hello_init);  

module_exit(hello_exit);  

在以上的Makefile里第一行修改为:

[cpp] view
plain copy

obj-m:=TestModule.o  

同样

[html] view
plain copy

make  

  

insmod TestModule.ko  

  

dmesg  

测试前,先看看是否已经建立了设备文件。 检查 /dev下是否有test设备文件,如果没有,那我们就手工建立一个。用前面看到的主设备号,使用命令: “mknod test c 268 0”  --引用博文

编写调用程序

[html] view
plain copy

[root@localhost module]# cat TestApp.c   

#include <stdio.h>  

#include <sys/stat.h>  

#include <fcntl.h>  

int main()  

{  

        char buf[20] = {0,};  

        int i = 0;  

        int p = open("/dev/test", O_RDWR);  

        if(p == -1)  

        {  

                printf("cannot open\n");  

                exit(0);  

        }  

        printf("buf addr %ui\r\n",buf);  

        read(p, buf, 10);  

        for(i = 0; i<10; i++)  

        {  

                printf("%s\r\n",buf+i);  

        }  

        close(p);  

        return 1;  

}  

编译

[html] view
plain copy

gcc TestApp.c -o TestApp  

运行

[cpp] view
plain copy

[root@localhost module]# ./TestApp   

buf addr 3218386872i  

==========  

=========  

========  

=======  

======  

=====  

====  

===  

==  

=  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: