(一) 编译测试binder驱动

binder驱动代码在drivers/android。在标准linux内核下,默认是不编译进去的。linux5.17.4 binder版本为8

wanqing@ThinkBook-15:~/data/kernel/linux-5.17.4/drivers/android$ ls *.c
binder_alloc.c  binder_alloc_selftest.c  binder.c  binderfs.c

binder.c和binder_alloc.c是 binder驱动核心文件,至少得编译这两个文件。
binderfs.c是binderfs文件系统,用于命名空间下单独挂载binder,现在android系统还没用到,看来谷歌是想android系统跑多个子系统,或者在服务器上一个内核跑多个android系统。这对于群控来说不错。

binder_alloc_selftest.c是用于调试测试的,每次ioctl binder fd都会调用binder_selftest_alloc测试。

# SPDX-License-Identifier: GPL-2.0-only
ccflags-y += -I$(src)           # needed for trace events

obj-$(CONFIG_ANDROID_BINDERFS)      += binderfs.o
obj-$(CONFIG_ANDROID_BINDER_IPC)    += binder.o binder_alloc.o
obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o


如果要将binder驱动编译进内核,需要在编译配置文件中设置,CONFIG_ANDROID_BINDERFS不是必须选项,CONFIG_ANDROID_BINDER_DEVICES这里设置为android10以上的binder配置

CONFIG_ANDROID=y
CONFIG_ANDROID_BINDERFS=y
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"

尝试挂载binder,测试ok。在最新的内核5.17中,如果binderfs编译进去,需要挂载binderfs,不然无法访问/dev/binder

root@arm64:~# mount -t binder none /dev/binderfs/
root@arm64:~# ls -al /dev/binderfs/
binder          features/       vndbinder       
binder-control  hwbinder

多了一个binder-control节点,binder-control支持添加binder设备。更加灵活了。这样可以不用更改内核,添加更改binder设备,这点改进挺好的。

测试代码

#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/fsuid.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/android/binder.h>
#include <linux/android/binderfs.h>


int main() {
  int result = 0;
  struct binderfs_device device = {0};
  struct binder_version version = {0};
  printf("binder test\n");

  char binderfs_path[512] = "/tmp/binder_XXXXXX";
  char device_path[256];
  if (mkdtemp(binderfs_path) == NULL){
    printf("mktemp %s  fail\n",binderfs_path);
    result = 1;
    goto end;
  }

  int ret = mount(NULL, binderfs_path, "binder", 0, 0);
  if (ret != 0) {
    result = 2;
    goto rmdir;
  }

  memcpy(device.name, "my-binder", strlen("my-binder"));


  snprintf(device_path, sizeof(device_path), "%s/binder-control", binderfs_path);
  int fd = open(device_path, O_RDONLY | O_CLOEXEC);
  if(fd<=0){
    result = 3;
    goto umount;
  }
  ret = ioctl(fd, BINDER_CTL_ADD, &device);
  close(fd);

  snprintf(device_path, sizeof(device_path), "%s/my-binder", binderfs_path);
  fd = open(device_path, O_CLOEXEC | O_RDONLY);

  if(fd<=0){
    printf("%s - Failed to open my-binder device\n",
           strerror(errno));
    result=4;
    goto umount;
  }
  ret = ioctl(fd, BINDER_VERSION, &version);
  if(ret<0){
    printf("%s - Failed to open perform BINDER_VERSION request\n",
           strerror(errno));
    result=5;
    goto umount;
  }
  printf("Detected binder version: %d", version.protocol_version);
  ret = unlink(device_path);
  if(ret!=0){
    printf("%s - Failed to delete binder device\n",
           strerror(errno));
    goto umount;
  }

  snprintf(device_path, sizeof(device_path), "%s/binder-control", binderfs_path);
  ret = unlink(device_path);
  if(ret==0){
    printf("Managed to delete binder-control device\n");
  }
  umount:
  ret = umount2(binderfs_path, MNT_DETACH);
  rmdir:
  ret = rmdir(binderfs_path);
  end:
  printf("result:%d\n",result);
  return result;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容