Android2.3及Linux2.6.29内核模拟器版本编译与调试
一、手动创建
1.驱动模块
test_driver.c
//#include <linux/devfs_fs_kernel.h> #include <linux/module.h> #include <linux/types.h> #include <linux/uaccess.h> #include <linux/miscdevice.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/platform_device.h> #define TEST_MAJOR 240 //动态设备节点 //struct class *mymodule_class; //结束 static int test_led_open(struct inode *inode, struct file *file) { printk("#########open######\n"); return 0; } static int test_led_close(struct inode *inode, struct file *file) { printk("#########release######\n"); return 0; } static int test_led_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) { printk("#########read######\n"); return count; } static int test_led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos) { printk("#########write######\n"); return count; } static struct file_operations led_fops = { .owner = THIS_MODULE, .open = test_led_open, .release = test_led_close, .read = test_led_read, .write = test_led_write, }; static int __init test_drv_init(void) { int rc; printk("test_driver dev\n"); //注册设备 rc = register_chrdev(TEST_MAJOR,"test_dev",&led_fops); if (rc <0){ printk ("register %s char dev error\n","led"); goto out_chrdev; } //devfs文件系统创建 /* devfs_mk_cdev( MKDEV(TEST_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, "test_dev"); */ //结束 //实现动态创建 //mymodule_class = class_create(THIS_MODULE, "test_dev");//在/sys/class/下创建“test_dev”目录 //device_create(mymodule_class, NULL, MKDEV(TEST_MAJOR, 0), NULL, "tankai_dev"); //在/dev/下创建“tankai_dev”文件 //结束 printk ("ok!\n"); return 0; out_chrdev: unregister_chrdev(TEST_MAJOR, "mymodule"); } static void __exit test_drv_exit(void) { //动态设备节点 //device_destroy(mymodule_class, MKDEV(TEST_MAJOR, 0)); //class_destroy(mymodule_class); //结束 unregister_chrdev(TEST_MAJOR, "test_dev"); } module_init(test_drv_init); module_exit(test_drv_exit); MODULE_AUTHOR("tank"); MODULE_LICENSE("GPL");
Makefile
obj-m := test_driver.o PWD := $(shell pwd) #KERNELDIR := /usr/src/linux-headers-3.0.0-26-generic/ KERNELDIR := /home/android2.3/android2.3_kernel/ default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules # cp -rf mini.ko ../module/ # cp -rf lddbus.ko ../module/ clean: rm *.mod.c *.o *.ko *.bak modules.* Module.*
2.Android模拟器没有mknod命令,我们实现它
mknod.c
#include <stdio.h> #include <fcntl.h> #define S_IFCHR 0020000 int main(int argc,char *argv[]) { if(argc != 3){ printf("error:Two canshu\n"); return -1; } char *devname = argv[1]; printf("devname is %s\n",devname); int devnum = -1; sscanf(argv[2],"%d",&devnum); printf("devnum is %d\n",devnum); if(mknod(devname,S_IFCHR|0666,makedev(devnum,0))!=0) perror("mknod"); return 0; }Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ mknod.c LOCAL_SHARED_LIBRARIES := \ libutils LOCAL_MODULE:= mknod LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE)
查看:cat /proc/devices
结果:Character devices: 1 mem 4 /dev/vc/0 4 tty 5 /dev/tty 5 /dev/console 5 /dev/ptmx 7 vcs 10 misc 13 input 14 sound 29 fb 90 mtd 116 alsa 128 ptm 136 pts 240 test_dev 253 ttyS 254 rtc Block devices: 1 ramdisk 259 blkext 7 loop 31 mtdblock 43 nbd 179 mmc 254 device-mapper
执行:./mknod /dev/tankai_dev 240
//这里只需要给出主设备号,主设备号相同的设备使用同一驱动程序;只是加入次设备号后可以实现一个驱动,多个设备使用的情况。这个目前我们的驱动中没有实现;因此,次设备号可以随便。
ll /dev/tankai_dev结果:
crw-rw-rw- root root 240, 0 2013-10-16 09:54 tankai_dev
3.测试用例
testdriver.c#include <fcntl.h> #include <stdlib.h> #include <sys/mman.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> int main(){ int fd = open("/dev/tankai_dev",O_RDWR,0); if(fd < 0) perror("testdriver"); printf("TK------->>>fd is %d\n",fd); char buf[20]; int result = read(fd,&buf,3); printf("TK------->>>readresult is %d,buf is %s\n",result,buf); strcpy(buf,"123"); result = write(fd,&buf,3); printf("TK------->>>writeresult is %d,buf is %s\n",result,buf); close(fd); return 0; }
Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ testdriver.c LOCAL_SHARED_LIBRARIES := \ libutils LOCAL_MODULE:= testdriver LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE)
二、自动创建
放通驱动中“创建”和“结束”部分代码;就不需要在执行mknod命令,设备节点会被创建,见:《Linux设备节点创建》内核kobject上报uevent过滤规则 及 《Linux设备节点创建》用户空间ueventd创建设备节点规则。