linux 如何在Android框架中通过service_manager和服务器Map“/dev/binde”文件?

xe55xuns  于 2023-06-21  发布在  Linux
关注(0)|答案(1)|浏览(103)

我现在正在分析android框架内部,我发现mmap()被android框架中的每个模块调用了两次,因为引用了同一个文件“dev/binder”。
1)有人能解释一下mmap()是如何两次刷新同一个文件的吗?
2)有人能解释一下mmap()在这种情况下是如何组织内存Map的吗?
1.---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BINDER_VM_SIZE:1M-8K
mDriverFD:引用“dev/binder”
public void run(){
mmap(0,BINDER_VM_SIZE,PROT_READ,MAP_PROVATE| MAP_NORESERVE,mDriverFD,0);
}
1.---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在service_manager.c中,binder_open()被如下调用。
Map大小:128 K
struct binder_state *binder_open(unsigned mapsize){
b = open(“dev/binder”,O_RDWR);
mmap(NULL,mapsize,PROT_READ,MAP_PRIVATE,bs->fd,0);
}
先谢谢你了。

4szc88ey

4szc88ey1#

这是你的答案我把它转成英语https://blog.csdn.net/mafei852213034/article/details/117783841
binder_open()的工作也相对简单;它分为以下步骤:
1.通过系统调用open()打开/dev/binder;获取句柄信息;在Binder驱动程序中,对应的函数binder_open()
1.通过ioctl获取绑定器的版本信息;比较绑定协议的版本是否相同;如果不一样,就会跳出来;在绑定器驱动程序中,对应的函数binder_ioctl()
1.通过mmap内存Map128 K内存空间;将绑定驱动文件的128 K字节Map到存储空间;该128 K存储器空间由服务管理器使用。Binder驱动程序中的相应函数是binder_mmap()。其他binder服务进程将MapBINDER_VM_SIZE((1 * 1024 * 1024)- sysconf(_SC_PAGE_SIZE)* 2)的内存空间;
sysconf(_SC_PAGE_SIZE)= 4096是1页大小。
service_manager.c

bs = binder_open(128*1024);
binder_become_context_manager(bs);

//在用户空间https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-9.0.0_r60/cmds/servicemanager/binder.c

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

BINDER_SET_CONTEXT_MGR为128K
////////////////////////////

#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))

ProcessState::ProcessState()
{
    ....
    mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
}

https://android.googlesource.com/platform/frameworks/native/+/jb-dev/libs/binder/IPCThreadState.cpp

#if defined(HAVE_ANDROID_OS)
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif

IPCThreadState.h

const   sp<ProcessState>    mProcess;

1 M-8 K用于使用onTransact的数据BINDER_WRITE_READ
//跟踪到linux驱动https://elixir.bootlin.com/linux/v5.13.19/source/drivers/android/binder.c#L4721

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    ....
    case BINDER_WRITE_READ:
        ret = binder_ioctl_write_read(filp, cmd, arg, thread);
        if (ret)
            goto err;
        break;

    case BINDER_SET_CONTEXT_MGR:
        ret = binder_ioctl_set_ctx_mgr(filp, NULL);
        if (ret)
            goto err;
        break;
}

相关问题