(一) 編譯測(cè)試binder驅(qū)動(dòng)

binder驅(qū)動(dòng)代碼在drivers/android。在標(biāo)準(zhǔn)linux內(nèi)核下,默認(rèn)是不編譯進(jìn)去的。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驅(qū)動(dòng)核心文件,至少得編譯這兩個(gè)文件。
binderfs.c是binderfs文件系統(tǒng),用于命名空間下單獨(dú)掛載binder,現(xiàn)在android系統(tǒng)還沒(méi)用到,看來(lái)谷歌是想android系統(tǒng)跑多個(gè)子系統(tǒng),或者在服務(wù)器上一個(gè)內(nèi)核跑多個(gè)android系統(tǒng)。這對(duì)于群控來(lái)說(shuō)不錯(cuò)。

binder_alloc_selftest.c是用于調(diào)試測(cè)試的,每次ioctl binder fd都會(huì)調(diào)用binder_selftest_alloc測(cè)試。

# 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驅(qū)動(dòng)編譯進(jìn)內(nèi)核,需要在編譯配置文件中設(shè)置,CONFIG_ANDROID_BINDERFS不是必須選項(xiàng),CONFIG_ANDROID_BINDER_DEVICES這里設(shè)置為android10以上的binder配置

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

嘗試掛載binder,測(cè)試ok。在最新的內(nèi)核5.17中,如果binderfs編譯進(jìn)去,需要掛載binderfs,不然無(wú)法訪問(wèn)/dev/binder

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

多了一個(gè)binder-control節(jié)點(diǎn),binder-control支持添加binder設(shè)備。更加靈活了。這樣可以不用更改內(nèi)核,添加更改binder設(shè)備,這點(diǎn)改進(jìn)挺好的。

測(cè)試代碼

#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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容