1 Android 驱动代码编译
参考https://www.sharetechnote.com/html/Linux_DeviceDriver_Programing.html#Device_Driver_HelloWorld编译ko文件调试驱动代码,将ko文件push到手机上验证
相关C文件testdriver.c
#include <linux/init.h>
#include <linux/module.h>
static int __init testdriver_init(void)
{
printk("Test Driver Initialized\n");
return 0;
}
static void __exit testdriver_exit(void)
{
printk("Test Driver Being Removed\n");
}
module_init(testdriver_init);
module_exit(testdriver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ShareTechnote");
MODULE_DESCRIPTION("Test Driver : The Simplest Driver");
MODULE_VERSION("1.0.0");
相关Make file文件如下
obj-m += testdriver.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
Make编译
编译成功后push到手机上data/data目录,安装后报错
insmod: failed to load testdriver.ko: Exec format error
原因1:内核版本不一致
手机内核版本,使用uname -r
电脑内核版本为:5.4.0-137-generic
原因2:网上搜索后需要使用ARM交叉编译
Make file参考网络建议修改Makefile,相关Make file文件如下
obj-m += testdriver.o
KDIR := ${OUT}/obj/KERNEL_OBJ/
$(info kdir is $(KDIR))
PWD := $(shell pwd)
$(info pwd is $(PWD))
default:
$(MAKE) CROSS_COMPILE=aarch64-linux-gnu- LLVM=1 LLVM_IAS=1 ARCH=arm64 -C $(KDIR) M=$(PWD) modules
编译报错,尝试各种方式无法解决该问题
解决方案:搜索相关MTK基线上相关代码,在vendor\mediatek\kernel_modules上有MTK加的相关KO文件的编译,添加Android.mk,修改Makefile如下
Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
$(info zmao android mk start)
LOCAL_MODULE := testdriver.ko
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_OWNER := mtk
LOCAL_SRC_FILES := \
testdriver.c \
Makefile
ifeq ($(TARGET_OUT_VENDOR),)
LOCAL_MODULE_PATH := $(ALPS_OUT)/vendor/lib/modules
else
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules
endif
$(info kernel mode is $(MTK_KERNEL_MODULE))
include $(MTK_KERNEL_MODULE)
Makefile文件
$(warning zmao start complie)
$(warning ########################### is $(srctree))
ccflags-y += -Wno-unused-variable
ldflags-y += -s
obj-m += testdriver.o
$(warning zmao success !!!!!!!)
成功编译出ko文件,push到手机上测试,成功安装驱动程序
2、调试驱动程序时出现 No such device or address Error
网上搜了很多,最后发现open函数没有执行,需要添加如下代码
printk("zmao init start \n");
cdev_init(&_cdev,&testdriver_fops);
_cdev.owner = THIS_MODULE;
_cdev.ops = &testdriver_fops;//Create Dev and file_operations Connected
cdev_add(&_cdev,first,1);
printk("zmao init end %d \n");
static int __init testdriver_init(void)
{
printk("zmao Test Driver Initialized\n");
if (alloc_chrdev_region(&first, 0, 3, "TestDriver") < 0)
{
return -1;
}
printk("zmao <Major, Minor>: <%d, %d>\n", MAJOR(first), MINOR(first));
if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL)
{
printk(KERN_INFO "class_create() failed");
unregister_chrdev_region(first, 1);
return -1;
}
if (device_create(cl, NULL, first, NULL, "testdriver") == NULL)
{
printk("zmao device_create() failed");
class_destroy(cl);
unregister_chrdev_region(first, 1);
return -1;
}
printk("zmao init start \n");
cdev_init(&_cdev,&testdriver_fops);
_cdev.owner = THIS_MODULE;
_cdev.ops = &testdriver_fops;//Create Dev and file_operations Connected
cdev_add(&_cdev,first,1);
printk("zmao init end %d \n");
return 0;
}
3、添加C进程访问内核驱动
Android.mk文件
LOCAL_PATH := $(call my-dir)
$(info start client compile ++++)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := rwtest.c
LOCAL_MODULE := rwtest
LOCAL_MODULE_CLASS := EXECUTABLES
$(info start client compile ----)
include $(BUILD_EXECUTABLE)
rwtest.c文件
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
int ret = 0;
char buff[100];
fd = open("/dev/testdriver",O_RDWR);
if(fd < 0) {
printf("/dev/testdriver open failed (ret = %d)\n",fd);
return 1;
};
ret = read(fd,buff,10);
printf("%s\n",buff);
ret = write(fd,"Hello",6);
close(fd);
return 1;
}