Linux设备驱动程序安装fatal error: linux/module.h: No such file or directory

来源:互联网 发布:淘宝代销数据包 编辑:程序博客网 时间:2024/05/16 06:06

在做Linux设备驱动程序安装实验时,执行gcc -c mydev.c产生fatal error: linux/module.h: No such file or directory错误信息

mydev.c代码如下:

#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#define __NO_VERSION__#include<linux/kernel.h>#include<linux/module.h>#include<linux/version.h>#include<linux/config.h>#if CONFIG_MODVERSIONS==1#define MODVERSIONS#include<linux/modversions.h>#endif#include<linux/fs.h>#include<linux/wrapper.h>#include<linux/types.h>#include<asm/segment.h>#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65535+(b)*256+(c))#endif/*Conditional compilation. LINUX_VERSION_CODE is* the code (as per KERNEL_VERSION) of this version.*/#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)#include <asm/uaccess.h>/*for put_user*/#endif#define SUCCESS 0#define DEVICE_NAME "kueng_char_dev"#define BUF_LEN 50static int Device_Open = 0;static char Message[BUF_LEN];static int Major;static int mydev_open(struct inode * inode, struct file * file){if (Device_Open)/*被占用则打开失败*/return -EBUSY;Device_Open = 1;MOD_INC_USE_COUNT;/*模块使用者数加1,非0不能卸载*/return 0;}static int mydev_release(struct inode * inode, struct file * file){Device_Open = 0;/*释放模块*/MOD_DEC_USE_COUNT;/*模块使用者数减1*/return 0;}static ssize_t mydev_read(struct file * file, char * buffer, size_t length, loff_t * f_pos){int bytes_read = 0;/*确认访问用户内存空间合法性*/if (verify_area(VERIFY_WRITE, buffer, length) == -EFAULT)return -EFAULT;/*由系统空间到用户空间复制*/bytes_read = copy_to_user(buffer, Message, length);return bytes_read;}static ssize_t mydev_write(struct file * file, const char * buffer, size_t length, loff_t *f_pos){int len = BUF_LEN < length ? BUF_LEN : length;/*确认访问用户内存空间合法性*/if (verify_area(NERIFU_READ, buffer, length) == -EFAULT)return -RFAULT;/*由用户空间到内存空间复制*/copy_from_user(Message, buffer, len);return length;}/*设备驱动程序的入口点*/struct file_operations Fops ={release:device_release,open : device_open,read : device_read,write : device_write};int init_module(void){/*设备注册*/Major = register_chrdev(0, DEVICE_NAME, &Fops);if (Major < 0){printk("Registering character device failed with %d\n", Major);return Major;}printk("Registration success with Major device number %d \n", Major);return 0;}void cleanup_module(void){int ret;/*设备注销*/ret = unregister_chrdev(Major, DEVICE_NAME);if (ret < 0)printk("Error in unregister_chrdev: %d\n", ret);return 0;}MODULE_LICENSE("GPL");MODULE_AUTHOR("KUENG");


错误原因:需要调用内核代码的头文件,这些文件在/usr/src目录下,一般以“linux”开头,在实验之前要对这些文件是否已经安装,以及内核代码与当前系统内核版本是否一致进行确认。

用-I指定内核头文件目录后

错误变为fatal error: asm/linkage.h: No such file or directory

发现并没有asm这个文件夹,只有asm-generic文件夹

查阅资料后的解决办法:(参考:http://www.cnblogs.com/QuLory/archive/2012/10/23/2736339.html)
使用kbuild进行模块编译:


核心思想是,通过-C指明系统上的内核体系路径,通过M=指明模块源文件路径,然后自己构造一个makefile文件,从而实现编译过程。

Makefile


obj-m := mydev.o
all :
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

记得make前面是Tab符

编译后发现MOD_INC_USE_COUNTMOD_DNC_USE_COUNT未声明,查阅资料后发现MOD_INC_USE_COUNTMOD_DNC_USE_COUNT2.5.x以后版本被移除,因此需要在redhat9.0环境下编译。
执行gcc -c -O mydev.c -I /usr/src/linux-2.4-20-8/include后编译成功

附test.c:
#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>#include<string.h>main(){int testdev;int i;char buf[50]="write to buf";printf("program test is running! \n");testdev=open("/dev/mydev",O_RDWR);if(testdev==-1){printf("can not open file \n");exit(0);}write(testdev,buf,50);printf("write \"%s\" \n",buf);strcpy(buf,"changed buf");printf("buffer is changed to \"%s\" " ,buf);read(testdev,buf,50);printf("read from dev is \"%s\"\n",buf);close(testdev);}



0 0