1 添加驱动
1.1 添加hello目录
在kernel/kernel/drivers/中创建hello, 并在其中添加hello.c, Makefile
hello.c:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/fcntl.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/ioctl.h>
MODULE_LICENSE("Dual BSD/GPL");
struct Hello_Dev
{
char *data;
struct cdev hello_cdev;
int GPIO;
}hello_dev;
unsigned int major =150;
unsigned int minor = 0;
dev_t devno = 0;
int device_open(struct inode* inode, struct file *flip)
{
printk("hello open\n");
return 0;
}
int device_read(struct file *flip, char *buf, size_t count, loff_t *f_ops)
{
printk("hello read\n");
return 0;
}
int device_write(struct file *flip, const char *buf, size_t count, loff_t *f_ops)
{
printk("hello write\n");
return 0;
}
int device_close(struct inode* inode, struct file *flip)
{
printk("hello close\n");
return 0;
}
int device_ioctl(struct file *filep,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case 0:
printk("hello ioctl 0\n");
break;
case 1:
printk("hello ioctl 1\n");
break;
default:
return -EINVAL;
}
return 0;
}
struct file_operations hello_fops=
{
.owner=THIS_MODULE,
.read=device_read,
.open=device_open,
.write=device_write,
.release=device_close,
.unlocked_ioctl=device_ioctl,
};
struct class *my_class;
static int hello_init(void)
{
int result = 0;
printk("Hello Init!\n");
if(major)
{
devno = MKDEV(major,minor);
result = register_chrdev_region(devno,1,"hello");
}
else
{
result = alloc_chrdev_region(&devno,minor,1,"hello");
major = MAJOR(devno);
minor = MINOR(devno);
}
if(result < 0)
{
printk("register devno errno!\n");
goto err0;
}
cdev_init(&(hello_dev.hello_cdev),&hello_fops);
hello_dev.hello_cdev.owner = THIS_MODULE;
result = cdev_add(&(hello_dev.hello_cdev),devno,1);
if(result < 0)
{
printk("cdev_add errno!\n");
goto err1;
}
my_class = class_create(THIS_MODULE,"my_class");
if(IS_ERR(my_class))
{
printk("Err: fail in creating class\n");
goto err1;
}
device_create(my_class,NULL,devno,NULL,"hello");
return 0;
err1:
unregister_chrdev_region(devno,1);
err0:
return result;
}
static void hello_exit(void)
{
printk("Hello Exit!\n");
cdev_del(&(hello_dev.hello_cdev));
device_destroy(my_class,devno);
class_destroy(my_class);
unregister_chrdev_region(devno,1);
}
module_init(hello_init);
module_exit(hello_exit);
Makefile:
obj-m +=hello.o
或者
Makefile (可以在hello目录直接make进行编译)
PWD = $(shell pwd)
KERNEL_SRC = /home/luke/Projects/freescale/android-imx6-kk4.4.2-1.0.0/kernel_imx/
CROSS_COMPILE = /home/luke/Projects/freescale/android-imx6-kk4.4.2-1.0.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-
obj-m := hello.o
all:
make ARCH=arm CFLAGS_MODULE=-fno-pic CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNEL_SRC) M=$(PWD) modules
clean:
make ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNEL_SRC) M=$(PWD) clean
1.2 更改Makefile
添加
obj-y +=hello/
到
kernel/kernel/drivers/Makefile
2. 验证
在/external/下创建helloTest目录,并创建文件main.c Android.mk, Makefile
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define DEVICE_NAME "/dev/hello"
int main()
{
int fd;
int ret;
char *i;
printf("\nstart hello test\n");
fd = open(DEVICE_NAME,O_RDWR);
//printf("fd=%d\n",fd);
if(fd == -1)
{
printf("open device %s error\n",DEVICE_NAME);
}
else
{
ioctl(fd,0);
ret = close(fd);
//printf("ret = %d\n",ret);
printf("close hello test end\n");
}
return 0;
}
Makefile:(不需要该文件)
hellotest:main.o
arm-linux-gcc -o main.o
main.o:main.c
arm-linux-gcc -c main.c
clean:
rm -f *.o helltest
Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main.c \
LOCAL_MODULE := helloTest
include $(BUILD_EXECUTABLE)