mmap内存 android,android的ashmem和pmem确实通过BpMemoryHeap和mmap完成了IPC通信

binder驱动binder_transaction

case BINDER_TYPE_FD: {

int target_fd;

struct file *file;

if (reply) {

if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {

binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fd_not_allowed;

}

} else if (!target_node->accept_fds) {

binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fd_not_allowed;

}

file = fget(fp->handle);

if (file == NULL) {

binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fget_failed;

}

target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);

if (target_fd < 0) {

fput(file);

return_error = BR_FAILED_REPLY;

goto err_get_unused_fd_failed;

}

task_fd_install(target_proc, target_fd, file);

binder_debug(BINDER_DEBUG_TRANSACTION,

"        fd %ld -> %d\n", fp->handle, target_fd);

/* TODO: fput? */

fp->handle = target_fd;

} break;

以上的file = fget(fp->handle)和task_get_unused_fd_flags共同完成dup包含操作集fops的file,然后assertReallyMapped将再次执行mmap,映射ashmem或pmem申请到的同一块物理内存.

BpMemoryHeap::assertReallyMapped

remote()->transact(HEAP_ID, data, &reply);

会被binder另一端的onTransact函数接收并处理

BnMemoryHeap::onTransact

status_t BnMemoryHeap::onTransact(

uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)

{

switch(code) {

case HEAP_ID: {

CHECK_INTERFACE(IMemoryHeap, data, reply);

reply->writeFileDescriptor(getHeapID());

reply->writeInt32(getSize());

reply->writeInt32(getFlags());

return NO_ERROR;

} break;

default:

return BBinder::onTransact(code, data, reply, flags);

}

}

status_t Parcel::writeFileDescriptor(int fd)

{

flat_binder_object obj;

obj.type = BINDER_TYPE_FD;

obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

obj.handle = fd;

obj.cookie = (void*)0;

return writeObject(obj, true);

}

void* BpMemoryHeap::getBase() const {

assertMapped();

return mBase;

}

BpMemoryHeap::assertMapped

void BpMemoryHeap::assertMapped() const

{

if (mHeapId == -1) {

spbinder(const_cast(this)->asBinder());

spheap(static_cast(find_heap(binder).get()));

heap->assertReallyMapped(); // 这会做实际的map工作

if (heap->mBase != MAP_FAILED) {

Mutex::Autolock _l(mLock);

if (mHeapId == -1) {

mBase   = heap->mBase;

mSize   = heap->mSize;

android_atomic_write( dup( heap->mHeapId ), &mHeapId );

}

} else {

// something went wrong

free_heap(binder);

}

}

}

void BpMemoryHeap::assertReallyMapped() const

{

if (mHeapId == -1) {

// remote call without mLock held, worse case scenario, we end up

// calling transact() from multiple threads, but that's not a problem,

// only mmap below must be in the critical section.

Parcel data, reply;

data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor());

status_t err = remote()->transact(HEAP_ID, data, &reply);

int parcel_fd = reply.readFileDescriptor(); // 在驱动binder_transaction中BINDER_TYPE_FD

// 然后remote的file结构体,在kernel中被执行file = fget(fp->handle);获取设备描述符号

ssize_t size = reply.readInt32();

uint32_t flags = reply.readInt32();

LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",

asBinder().get(), parcel_fd, size, err, strerror(-err));

int fd = dup( parcel_fd );

LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",

parcel_fd, size, err, strerror(errno));

int access = PROT_READ;

if (!(flags & READ_ONLY)) {

access |= PROT_WRITE;

}

Mutex::Autolock _l(mLock);

if (mHeapId == -1) {

mRealHeap = true;

mBase = mmap(0, size, access, MAP_SHARED, fd, 0);

if (mBase == MAP_FAILED) {

LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",

asBinder().get(), size, fd, strerror(errno));

close(fd);

} else {

mSize = size;

mFlags = flags;

android_atomic_write(fd, &mHeapId);

}

}

}

}

BootAnimation::BootAnimation() : Thread(false)

{

mSession = new SurfaceComposerClient(); // 与SurfaceFlinger创建一个Connection,也叫session

}

SurfaceComposerClient::SurfaceComposerClient()

spsm(getComposerService()); // 就是binder获取"SurfaceFlinger"系统服务,即SurfaceFlinger::instantiate()添加的service

_init(sm, sm->createConnection());

SurfaceFlinger::createConnection()

==> spclient = new Client(token, this);

==> spbclient =

new BClient(this, token, client->getControlBlockMemory());

frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp

Client::Client(ClientID clientID, const sp& flinger)

: ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)

{

const int pgsize = getpagesize();

const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));

mCblkHeap = new MemoryHeapBase(cblksize, 0,

"SurfaceFlinger Client control-block");

ctrlblk = static_cast(mCblkHeap->getBase());

if (ctrlblk) { // construct the shared structure in-place.

new(ctrlblk) SharedClient;

}

}

首先在上面通过createConnection()创建一个client,然后才能创建SurfaceFlinger::createSurface

SurfaceComposerClient::createSurface

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值