Android内核开发 内核模块编程编译及安卓虚拟机测试
配置交叉编译环境见《Android内核开发 Goldfish Linux Kernel编译及安卓虚拟机测试》Makefile文件注意Linux kernel源码目录需要提前编译,否则内核模块会编译出错。
·
本文出处: 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:/ #
更多推荐
已为社区贡献3条内容
所有评论(0)