本文出處: http://blog.csdn.net/leytton/article/details/52738901
html
本文目的爲Linux系統環境下:一、編寫內核模塊程序並編譯 二、加載內核模塊 三、編寫C程序調用內核模塊linux
功能爲向內核模塊虛擬設備寫如字符串,再從內核模塊虛擬設備讀出字符串長度。shell
一、word_count.c文件
centos
#include<linux/module.h> #include<linux/init.h> #include<linux/kernel.h> #include<linux/fs.h> #include<linux/miscdevice.h> #include<asm/uaccess.h> //設備文件名 #define DEVICE_NAME "word_count" //保存讀寫字符串 static unsigned char mem[1000]; //讀寫字符串中字符數量,ssize_t有符號int,size_t無符號int static ssize_t char_count=0; // 從設備文件讀取數據時調用該函數 // file:指向設備文件、buf:保存可讀取的數據 count:可讀取的字節數 ppos:讀取數據的偏移量 static ssize_t word_count_read(struct file *file,char __user *buf,size_t read_count,loff_t *ppos) { read_count = char_count; //printk("read:debug:%d\n",(int)char_count); // 將內核空間的數據複製到用戶空間,buf中的數據就是從設備文件中讀出的數據 //if(copy_to_user(buf, (void*)mem,read_count)){ if(copy_to_user(buf, &char_count,read_count)){//注意與以前不同,此次返回字符長度 return -EINVAL; } printk("read:read_count:%d\n",(int)read_count); char_count=0; return read_count; } // 向設備文件寫入數據時調用該函數 // file:指向設備文件、buf:保存寫入的數據 count:寫入數據的字節數 ppos:寫入數據的偏移量 static ssize_t word_count_write(struct file *file,const char __user *buf,size_t write_count,loff_t *ppos) { char_count=write_count; // 將用戶空間的數據複製到內核空間,mem中的數據就是向設備文件寫入的數據 if(copy_from_user((void*)mem,buf,write_count)){ return -EINVAL; } mem[write_count]='\0'; printk("write:write_count:%d\n",(int)char_count); return char_count; } static struct file_operations dev_fops= {.owner=THIS_MODULE, .read=word_count_read, .write=word_count_write}; static struct miscdevice misc= {.minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME, .fops=&dev_fops}; //Linux驅動裝載函數 static int __init word_count_init(void) { int ret; //註冊設備文件 ret=misc_register(&misc); printk("word_count init success!"); return ret; } //Linux驅動卸載函數 static void __exit word_count_exit(void) { // 註銷(移除)設備文件 misc_deregister(&misc); printk("word_count exit success!"); }
TARGET=word_count KDIR=/usr/src/kernels/3.10.0-327.el7.x86_64 # centos PWD=$(shell pwd) obj-m:=$(TARGET).o default: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.o *.mod.o *.mod.c *.symvers *.order
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <string.h> int main( int argc, char *argv[] ) { /* 打開設備文件(/dev/word_count)的句柄 */ int devret; int word_count=0; int write_count=0; /* 打開設備文件 */ devret = open( "/dev/word_count", O_RDWR ); /* 若是open函數返回-1,表示打開設備文件失敗 */ if ( devret == -1 ) { printf( "Cann't open file \n" ); return(0); } /* * 若是word_count_test後面跟有命令行參數,程序會將第1個參數值看成待統計的字符串 * 若是沒有命令行參數,則只讀取設備文件中的值 */ if ( argc > 1 ) { /* 向設備文件寫入待統計的字符串 */ write_count=write( devret, argv[1], strlen( argv[1] ) ); /* 輸出待統計的字符串 */ printf( "write string:%s,count:%d\n", argv[1],write_count ); } // 讀取設備文件中的單詞數 read(devret, &word_count, sizeof(word_count)); // 輸出統計出的單詞數 printf("word count:%d\n", word_count); /* 關閉設備文件 */ close( devret ); return(0); } //註冊裝載函數 module_init(word_count_init); //註冊卸載函數 module_exit(word_count_exit); MODULE_AUTHOR("Leytton"); MODULE_DESCRIPTION("A simple Word Count Driver"); MODULE_ALIAS("a simplest module"); MODULE_LICENSE("MIT");
四、編譯內核模塊函數
[hadoop@localhost drivers01]$ make make -C /usr/src/kernels/3.10.0-327.el7.x86_64 M=/mnt/workbench/workspace/drivers01 modules make[1]: 進入目錄「/usr/src/kernels/3.10.0-327.el7.x86_64」 CC [M] /mnt/workbench/workspace/drivers01/word_count.o Building modules, stage 2. MODPOST 1 modules CC /mnt/workbench/workspace/drivers01/word_count.mod.o LD [M] /mnt/workbench/workspace/drivers01/word_count.ko make[1]: 離開目錄「/usr/src/kernels/3.10.0-327.el7.x86_64」 [hadoop@localhost drivers01]$
五、加載內核模塊oop
[hadoop@localhost drivers01]$ sudo insmod word_count.ko [sudo] password for hadoop: [hadoop@localhost drivers01]$
六、編譯word_count_test.c文件測試
gcc word_count_test.c -o word_count_test
七、執行word_count_testui
[hadoop@localhost drivers01]$ sudo ./word_count_test hello12345 write string:hello12345,count:10 word count:10
注意要用root權限執行,不然會返回如下錯誤spa
[hadoop@localhost drivers01]$ ./word_count_test hello12345
Cann't open file
.net
八、查看內核模塊日誌
[hadoop@localhost drivers01]$sudo dmesg -c [15074.261371] write:write_count:10 [15074.261415] read:read_count:10九、參考文章
《開發可統計單詞個數的Android驅動程序(3)》http://www.cnblogs.com/nokiaguy/archive/2013/03/11/2954618.html
《在Android模擬器和Ubuntu上測試Linux驅動》 http://www.cnblogs.com/nokiaguy/archive/2013/03/14/2960408.html
《 Android深度探索(卷1):HAL與驅動開發》http://blog.csdn.net/nokiaguy/article/details/8540127
《Android驅動與HAL開發實戰視頻課程》http://edu.51cto.com/course/course_id-2323.html