本文出处: http://blog.csdn.net/leytton/article/details/52738901

本文目的为Linux系统环境下:1、编写内核模块程序并编译 2、加载内核模块 3、编写C程序调用内核模块

功能为向内核模块虚拟设备写如字符串,再从内核模块虚拟设备读出字符串长度。

1、word_count.c文件

#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!");
}

2、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

3、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");

4、编译内核模块

[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.oBuilding modules, stage 2.MODPOST 1 modulesCC      /mnt/workbench/workspace/drivers01/word_count.mod.oLD [M]  /mnt/workbench/workspace/drivers01/word_count.ko
make[1]: 离开目录“/usr/src/kernels/3.10.0-327.el7.x86_64”
[hadoop@localhost drivers01]$ 

5、加载内核模块

[hadoop@localhost drivers01]$ sudo insmod word_count.ko
[sudo] password for hadoop:
[hadoop@localhost drivers01]$

6、编译word_count_test.c文件

gcc word_count_test.c -o word_count_test

7、执行word_count_test

[hadoop@localhost drivers01]$ sudo ./word_count_test hello12345
write string:hello12345,count:10
word count:10

注意要用root权限执行,否则会返回以下错误

[hadoop@localhost drivers01]$ ./word_count_test hello12345
Cann't open file

8、查看内核模块日志

[hadoop@localhost drivers01]$sudo dmesg -c
[15074.261371] write:write_count:10
[15074.261415] read:read_count:10

9、参考文章

《开发可统计单词个数的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

转载于:https://www.cnblogs.com/leytton/p/8253294.html

Android内核开发 Linux C编程调用内核模块设备驱动相关推荐

  1. 挑战360无死角讲解Linux内核 进程管理,调度器的5种实现丨C++后端开发丨C/C++Linux服务器开发丨内核开发丨网络编程

    挑战360无死角讲解 进程管理,调度器的5种实现 1. 8500行 CFS是什么 2. RT调度器使用场景 3. IDLE/Dealine调度器 视频讲解如下,点击观看: 挑战360无死角讲解Linu ...

  2. Android内核开发:源码的版本与分支详解

    我想很多初学者或许跟我一样,看完Android源码下载相关的文章以后,就开始兴致勃勃地去下载Android源码了,但是下载完了源码后,有没有像我一样产生如下几个困惑呢? (1) Android版本有哪 ...

  3. Android应用开发:网络编程-2

    网络编程 Java基础:网络编程 Uri.URL.UriMatcher.ContentUris详解 Android应用开发:网络编程1 Android应用开发:网络编程2 1. 使用HttpClien ...

  4. Android应用开发:网络编程-1

    网络编程 Java基础:网络编程 Uri.URL.UriMatcher.ContentUris详解 Android应用开发:网络编程1 Android应用开发:网络编程2 1. 请求网络图片 网络交互 ...

  5. Android内核开发:学会分析系统的启动log

    本文是<Android内核开发>系列的第八篇文章,本文主要关注如何分析Android系统的启动log,学会通过搜索重要的TAG标签,找到Android启动过程中的重要节点. 要学会分析系统 ...

  6. Android内核开发:系统编译输出的镜像文件

    本文是<Android内核开发>的第四篇文章,主要介绍一下源码编译输出的几个重要的镜像文件,这里把bootloader源码和Linux内核源码的编译输出也算在其中,因为毕竟Android系 ...

  7. Android内核和Linux内核的区别

    1.Android系统层面的底层是Linux,并且在中间加上了一个叫做Dalvik的Java虚拟机,从表面层看是Android运行库.每个Android应用都运行在自己的进程上,享有Dalvik虚拟机 ...

  8. Android内核开发:系统启动速度优化

    在学习新知识的过程中,我一直很推荐结合实战任务去学习,只有经历实战,才能加深对理论知识的理解.<Android内核开发>系列已经写了八篇了,本文就结合前面的内容,给大家布置一个实战任务:  ...

  9. Android内核开发:图解Android系统的启动过程

    本文是<Android内核开发>系列的第六篇文章,前面的几篇文章介绍了Android内核开发相关的基础知识,包括:Android源码的下载.版本和分支介绍.编译和烧写等等,从本文起就要开始 ...

最新文章

  1. win7 能下node什么版本_Node.js 版本知多少?又该如何选择?
  2. python-day22(序列化)
  3. mysql数据库的介绍及安装
  4. 天马行空W:在C++中调用DLL中的函数
  5. 014_html折行
  6. 中科大镜像源_JETPACK4.4安装软件和备份镜像的方法介绍
  7. win10安装mysql5.7.15_win10上如何安装mysql5.7.16(解压缩版)
  8. Could not load type 'System.DateTimeOffset'的问题
  9. mac os x 10.7下配置svn服务器
  10. python中os关于目录创建和文件移动操作
  11. 黑马python就业班_2017年最新黑马Python2017年就业班不加密视频教程
  12. 小学计算机英语,小学英语电脑版
  13. 阿里云80端口无法访问
  14. uniapp支付宝登录获取用户信息
  15. MIB Browser的使用(附安装包)
  16. 一次简单的PC游戏汉化
  17. LeetCode46:全排列(八皇后)
  18. C# Serializable
  19. 为什么Facebook需要养号?Facebook养号系统有什么作用?
  20. 2016,解密百度排名规则与算法

热门文章

  1. mysql存储过程详细教程
  2. cholesky分解_Time Series Analysis-1.2 LDL分解
  3. Python 语言程序设计(1)
  4. cad 打开硬件加速卡_CAD画图卡顿?电脑带不动?4个简单实用的方法,解决CAD运行卡顿问题...
  5. sublime 设置自动更新_Win10关闭自动更新的三种方法
  6. 逻辑回归与梯度下降法
  7. 系统学习深度学习(二十三)--SqueezeNet
  8. python统计数据库中每个数的个数,如何统计每个数据库中每个集合中的文档数?...
  9. 如何分析一个“排序算法”?
  10. Java8函数式编程详解