Android11(RK3568)自定义服务制作(3)-Hardware制作和权限管理

本文详细介绍了在Android 11 (RK3568) 上创建自定义服务并与内核驱动进行交互的步骤。通过JNI在硬件层实现设备打开、关闭接口以及设备访问接口,同时展示了Android.bp和Android.mk文件的配置,以及如何编写相应的selinux策略以确保安全。
摘要由CSDN通过智能技术生成

根据上一篇Android11(RK3568)自定义服务制作(2)-Service制作 完成了系统service的注册后,进一步就要完成Hardware层的制作,完成自定义service跟kernel驱动的调用。

通过Service调用Kernel驱动的最简单方法就是用JNI。

首先在hardware/libhardware/modules/下创建hello文件夹,并在hello文件夹中添加hello.c文件

#define LOG_TAG "HelloStub"

#include <hardware/hardware.h>
#include <hardware/hello.h>
// #include <fcntl.h>
#include <errno.h>
#include <cutils/log.h>
#include <cutils/atomic.h>

#include <malloc.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

#define DEVICE_NAME "/dev/hello"
#define MODULE_NAME "Hello"
#define MODULE_AUTHOR "sommer_jiang@163.com"

/*设备打开和关闭接口*/
static int hello_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device);
static int hello_device_close(struct hw_device_t *device);

/*设备访问接口*/
static int hello_set_val(struct hello_device_t *dev, int val);
static int hello_get_val(struct hello_device_t *dev, int *val);

static int hello_device_open(const struct hw_module_t *module, const char *name, struct hw_device_t **device)
{
    struct hello_device_t *dev;
    dev = (struct hello_device_t *)malloc(sizeof(struct hello_device_t));

    if (!dev)
    {
        ALOGE("Hello Stub: failed to alloc space");
        return -EFAULT;
    }

    memset(dev, 0, sizeof(struct hello_device_t));
    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = 0;
    dev->common.module = (hw_module_t *)module;
    dev->common.close = hello_device_close;
    dev->set_val = hello_set_val;
    dev->get_val = hello_get_val;

    if ((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1)
    {
        ALOGE("Hello Stub: failed to open /dev/hello -- %s.", strerror(errno));
        free(dev);
        return -EFAULT;
    }

    *device = &(dev->common);
    ALOGI("Hello Stub: open /dev/hello successfully.");
    ALOGI("Hello Stub: name -- %s.", name);
    return 0;
}

static int hello_device_close(struct hw_device_t *device)
{
    struct hello_device_t *hello_device = (struct hello_device_t *)device;

    if (hello_device)
    {
        close(hello_device->fd);
        free(hello_device);
    }

    return 0;
}

static int hello_set_val(struct hello_device_t *dev, int val)
{
    ALOGI("Hello Stub: set value %d to device.", val);

    write(dev->fd, &val, sizeof(val));

    return 0;
}

static int hello_get_val(struct hello_device_t *dev, int *val)
{
    if (!val)
    {
        ALOGE("Hello Stub: error val pointer");
        return -EFAULT;
    }

    read(dev->fd, val, sizeof(*val));

    ALOGI("Hello Stub: get value %d from device", *val);

    return 0;
}

/*模块方法表*/
static struct hw_module_methods_t hello_module_methods = {
    .open = hello_device_open};

/*模块实例变量*/
struct hello_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .version_major = 1,
        .version_minor = 0,
        .id = HELLO_HARDWARE_MODULE_ID,
        .name = MODULE_NAME,
        .author = MODULE_AUTHOR,
        .methods = &hello_module_methods,
    }};

并在相同的目录写下Android.bp,内容如下:

// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

cc_library_shared {
    name: "hello.default",
    relative_install_path: "hw",
    proprietary: true,
    srcs: ["hello.c"],
    cflags: ["-Wall", "-Werror"],
    header_libs: ["libhardware_headers"],
    shared_libs: ["liblog"],
}

接下来在hardware/libhardware/include/hardware/中添加供引用的hello.h文件


    #ifndef ANDROID_HELLO_INTERFACE_H  
    #define ANDROID_HELLO_INTERFACE_H  
    #include <hardware/hardware.h>  
      
    __BEGIN_DECLS  
      
    /*定义模块ID*/  
    #define HELLO_HARDWARE_MODULE_ID "hello"  
      
    /*硬件模块结构体*/  
    struct hello_module_t {  
        struct hw_module_t common;  
    };  
      
    /*硬件接口结构体*/  
    struct hello_device_t {  
        struct hw_device_t common;  
        int fd;  
        int (*set_val)(struct hello_device_t* dev, int val);  
        int (*get_val)(struct hello_device_t* dev, int* val);  
    };  
      
    __END_DECLS  
      
    #endif  

这几个完成后别忘了在/hardware/libhardware/Android.mk中添加以下硬件模块

hardware_modules := \
    hello

添加完这些后,可以采用mmm编译整个libhardware来把硬件驱动层完成。

完成了硬件驱动层后,最艰难痛苦的一步来了,就是selinux的填写。其实按照规律也不是很难填写。

/device/rockchip/common/sepolicy/vendor/device.te添加以下设备

#sommerjiang 20211101 add
type hello_device, dev_type;

/device/rockchip/common/sepolicy/vendor/domain.te添加以下代码

#sommerjiang 20211101 add
allow domain hello_device:chr_file rw_file_perms;

/device/rockchip/common/sepolicy/vendor/file_contexts添加以下代码

//sommer.jiang,20211115,add for /dev/hello
/dev/hello         u:object_r:hello_device:s0

/device/rockchip/common/sepolicy/private/service_contexts添加以下代码

hello                                          u:object_r:hello_service:s0

/device/rockchip/common/sepolicy/vendor/service.te添加以下代码

type hello_service,                 system_api_service, system_server_service, service_manager_type;

/device/rockchip/common/sepolicy/vendor/system_app.te添加以下代码

#sommerjiang 20211101 add
allow system_app hello_service:service_manager find;

/device/rockchip/common/sepolicy/vendor/system_server.te添加以下代码

#sommerjiang 20211101 add
allow system_server hello_device:chr_file rw_file_perms;
allow system_server hello_service:service_manager {add };

device/rockchip/common/sepolicy/vendor/untrusted_app.te添加以下代码

#sommer.jiang add
allow untrusted_app hello_service:service_manager find;

至此,所有的中间层都完成了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值