Android内核开发 内核模块编程编译及安卓虚拟机测试

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


1、配置交叉编译环境

见《Android内核开发 Goldfish Linux Kernel编译及安卓虚拟机测试


2、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)){
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("count_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!");
}

//注册装载函数
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");

3、Makefile文件

注意Linux kernel源码目录需要提前编译,否则内核模块会编译出错。见《Android内核开发 Goldfish Linux Kernel编译及安卓虚拟机测试

TARGET=word_count
KDIR=/mnt/workbench/android-goldfish-3.4 #Linux kernel源码目录
PWD=$(shell pwd)
ARCH=arm
CROSS_COMPILE=arm-linux-androideabi-
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
obj-m:=$(TARGET).o
default:
make EXTRA_CFLAGS="-D_CONFIG_ARM_ -fno-pic" -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.o *.mod.o *.mod.c *.symvers *.order

make编译

make clean清除编译过程中生成的垃圾文件

【注意 测试时不加EXTRA_CFLAGS="-D_CONFIG_ARM_ -fno-pic" 加载内核模块时会出现错误 insmod: init_module 'word_count.ko' failed (Exec format error)】



4、adb连接Android虚拟机加载内核模块

adt-bundle-linux-x86_64-20140702/sdk/platform-tools目录下
[hadoop@localhost platform-tools]$ ./adb push word_count.ko /llqqww/
130 KB/s (5968 bytes in 0.044s)
[hadoop@localhost platform-tools]$ ./adb shell
root@generic:/ # dmesg -c
255|root@generic:/ #insmod /llqqww/word_count.ko                               
root@generic:/ # echo hello > /dev/word_count
root@generic:/ # cat /dev/word_count
hello
root@generic:/ # 
root@generic:/ # rmmod word_count.ko
root@generic:/ # dmesg
word_count init success!
count_write:write_count:6
<4>read:read_count:6
<4>read:read_count:0
<4>word_count exit success!
root@generic:/ #



posted @ 2016-10-05 03:10  Leytton  阅读(583)  评论(0编辑  收藏  举报