Linux裝置驅動程式安裝fatal error: linux/module.h: No such file or directory
阿新 • • 發佈:2019-01-03
在做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 50 static 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檔案,從而實現編譯過程。
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_COUNT、MOD_DNC_USE_COUNT未宣告,查閱資料後發現MOD_INC_USE_COUNT、MOD_DNC_USE_COUNT在2.5.x以後版本被移除,因此需要在redhat9.0環境下編譯。
#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);
}