Android內核開發 Linux C編程調用內核模塊設備驅動

本文出處: 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!");
}

二、Makefile文件

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

三、word_count_test.c文件
#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

相關文章
相關標籤/搜索