Binder学习一 ServiceManager初始化

Service Manger的初始化分析 在init.rc文件中,有定义serviceservicemanager /system/bin/servicemanager,在系统初始化会解析init.rc文件时,遇到这句话,将会把servicemanager加载到服务启动列表中,同时它也是第一个启动的服务。          ServiceManager的相关代码位于frameworks/native/cmds/servicemanage 阅读详情

Binder内核设备作用:

1.实现跨进程IPC调用

2.跟踪跨进程binder对象的引用计数。包括映射远程进程中的对象引用到真实对象的宿主进程中,以及确保被远程对象使用的对象不被删除。


binder用户空间代码作用:

在binder所在进程中维护一个线程池,用来处理binder设备发来的IPC请求。


Service Manager处理流程如下:

1.Service manager打开binder设备

2.Service Manager进入Loop,等待客户端通过Binder发出指令,此时Binder设备将ServiceManager主线程挂起,如a1所示.

3.客户端通过Binder发出请求,请求数据放在binder_write_read结构中,此时Binder设备将Thread1,Thread2线程挂起,如a2,a3步骤所示

4.Binder唤醒ServiceManager主线程,处理客户请求

5.Binder唤醒Thread1,Thread2线程,得到最终结果


                                                                                                                 Service Manage处理原理

ServiceManager初始化过程:

1.Open binder device /dev/binder

frameworks/base/cmds/servicemanager/service_manager.c

int main(int argc, char **argv)
{
    struct binder_state *bs;
    void *svcmgr = BINDER_SERVICE_MANAGER;

    bs = binder_open(128*1024);  //打开binder设备,设置映射内存大小为128KB

    if (binder_become_context_manager(bs)) { //设置自身为
        LOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }

    svcmgr_handle = svcmgr;
    binder_loop(bs, svcmgr_handler);     //在其中直接读写binder并处理service添加请求
    return 0;
}

frameworks/base/cmds/servicemanager/Binder.c

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
void binder_loop(struct binder_state *bs, binder_handler func)
{...
res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
...}
 

struct binder_state *binder_open(unsigned mapsize)
{
    struct binder_state *bs;

    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return 0;
    }

    bs->fd = open("/dev/binder", O_RDWR);  //调用到设备对应处理函数int binder_open(struct inode *nodp, struct file *filp)
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open device (%s)\n",
                strerror(errno));
        goto fail_open;
    }

    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }

        /* TODO: check version */

    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return 0;
}

2.进入loop等待binder客户端指令

frameworks/base/cmds/servicemanager/Binder.c

void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    unsigned readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;
    
    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(unsigned)); //初始指令

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (unsigned) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); //第一次执行时会被binder设备挂起,直到binder设备发送指令

        if (res < 0) {
            LOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); //解析binder设备指令
        if (res == 0) {
            LOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            LOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}

int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{...
        case BR_TRANSACTION: { //此处处理servicemanager的事务
            struct binder_txn *txn = (void *) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("parse: txn too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (func) {
                unsigned rdata[256/4];
                struct binder_io msg;
                struct binder_io reply;
                int res;

                bio_init(&reply, rdata, sizeof(rdata), 4);
                bio_init_from_txn(&msg, txn);
                res = func(bs, txn, &msg, &reply); //这里调用svcmgr_handler,实现service添加,获取,列举等功能

                binder_send_reply(bs, &reply, txn->data, res);
            }
            ptr += sizeof(*txn) / sizeof(uint32_t);
            break;
        }
        case BR_REPLY: {
            struct binder_txn *txn = (void*) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("parse: reply too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (bio) {
                bio_init_from_txn(bio, txn);
                bio = 0;
            } else {
                    /* todo FREE BUFFER */
            }
            ptr += (sizeof(*txn) / sizeof(uint32_t));
            r = 0;
            break;
        }
        case BR_DEAD_BINDER: {
            struct binder_death *death = (void*) *ptr++;
            death->func(bs, death->ptr);
            break;
        }
...    }

    return r;
}


以下为ServiceManager事务处理代码,实现服务列表,获取,添加,检查等功能:


frameworks/base/cmds/servicemanager/service_manager.c

int svcmgr_handler(struct binder_state *bs,
                   struct binder_txn *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    unsigned len;
    void *ptr;
    uint32_t strict_policy;

    if (txn->target != svcmgr_handle)
        return -1;
...
    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        ptr = do_find_service(bs, s, len);
        if (!ptr)
            break;
        bio_put_ref(reply, ptr);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        ptr = bio_get_ref(msg);
        if (do_add_service(bs, s, len, ptr, txn->sender_euid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        unsigned n = bio_get_uint32(msg);

        si = svclist;
        while ((n-- > 0) && si)
            si = si->next;
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
        }
        return -1;
    }
    default:
        LOGE("unknown code %d\n", txn->code);
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}

以下为Binder设备内核代码:

kernel/omap4/drivers/staging/android/Binder.c

static int binder_open(struct inode *nodp, struct file *filp)
{
	struct binder_proc *proc;

	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
		     current->group_leader->pid, current->pid);

	proc = kzalloc(sizeof(*proc), GFP_KERNEL); //对应每一次打开设备操作,创建对应的proc来保留调用进程信息
	if (proc == NULL)
		return -ENOMEM;
	get_task_struct(current);
	proc->tsk = current;
	INIT_LIST_HEAD(&proc->todo);
	init_waitqueue_head(&proc->wait); //每个设备用户仅拥有一个wait queue
	proc->default_priority = task_nice(current);
	mutex_lock(&binder_lock);
	binder_stats_created(BINDER_STAT_PROC);
	hlist_add_head(&proc->proc_node, &binder_procs);
	proc->pid = current->group_leader->pid;
	INIT_LIST_HEAD(&proc->delivered_death);
	filp->private_data = proc;
	mutex_unlock(&binder_lock);

	if (binder_debugfs_dir_entry_proc) {
		char strbuf[11];
		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
		proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
			binder_debugfs_dir_entry_proc, proc, &binder_proc_fops);
	}

	return 0;
}


binder_ioctl是binder设备的入口函数,主要处理BINDER_WRITE_READ命令来实现和binder service的联系。

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
	struct binder_proc *proc = filp->private_data;
	struct binder_thread *thread;
	unsigned int size = _IOC_SIZE(cmd);
	void __user *ubuf = (void __user *)arg;

	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); //如果binder有错误,挂起线程
	if (ret)
		return ret;

	mutex_lock(&binder_lock);
	thread = binder_get_thread(proc);
	if (thread == NULL) {
		ret = -ENOMEM;
		goto err;
	}
    switch (cmd) {
    case BINDER_WRITE_READ: {
        struct binder_write_read bwr;
        if (size != sizeof(struct binder_write_read)) {
            ret = -EINVAL;
            goto err;
        }
        if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
            ret = -EFAULT;
            goto err;
        }
        binder_debug(BINDER_DEBUG_READ_WRITE,
                 "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
                 proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
                 bwr.read_size, bwr.read_buffer);

        if (bwr.write_size > 0) {
            ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
            if (ret < 0) {
                bwr.read_consumed = 0;
                if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
                    ret = -EFAULT;
                goto err;
            }
        }
        if (bwr.read_size > 0) {
            ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
            if (!list_empty(&proc->todo))
                wake_up_interruptible(&proc->wait);
            if (ret < 0) {
                if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
                    ret = -EFAULT;
                goto err;
            }
        }
        binder_debug(BINDER_DEBUG_READ_WRITE,
                 "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
                 proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
                 bwr.read_consumed, bwr.read_size);
        if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
            ret = -EFAULT;
            goto err;
        }
        break;
    }
...
err:
    if (thread)
        thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
    mutex_unlock(&binder_lock);
    wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
    if (ret && ret != -ERESTARTSYS)
        printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
    return ret;
}


函数binder_thread_read将读取binder service端指令,如果无则挂起线程直到有指令。

static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      void  __user *buffer, int size,
			      signed long *consumed, int non_block)
{
retry:
    wait_for_proc_work = thread->transaction_stack == NULL &&
                list_empty(&thread->todo); //如果此binder事务队列栈为空且todo list为空

    if (thread->return_error != BR_OK && ptr < end) {
        if (thread->return_error2 != BR_OK) {
            if (put_user(thread->return_error2, (uint32_t __user *)ptr))
                return -EFAULT;
            ptr += sizeof(uint32_t);
            if (ptr == end)
                goto done;
            thread->return_error2 = BR_OK;
        }
        if (put_user(thread->return_error, (uint32_t __user *)ptr))
            return -EFAULT;
        ptr += sizeof(uint32_t);
        thread->return_error = BR_OK;
        goto done;
    }


    thread->looper |= BINDER_LOOPER_STATE_WAITING;
    if (wait_for_proc_work)
        proc->ready_threads++;
    mutex_unlock(&binder_lock);
    if (wait_for_proc_work) {
        if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
                    BINDER_LOOPER_STATE_ENTERED))) {
            binder_user_error("binder: %d:%d ERROR: Thread waiting "
                "for process work before calling BC_REGISTER_"
                "LOOPER or BC_ENTER_LOOPER (state %x)\n",
                proc->pid, thread->pid, thread->looper);
            wait_event_interruptible(binder_user_error_wait,
                         binder_stop_on_user_error < 2);
        }
        binder_set_nice(proc->default_priority);
        if (non_block) {
            if (!binder_has_proc_work(proc, thread))
                ret = -EAGAIN;
        } else
            ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
    } else {
        if (non_block) {
            if (!binder_has_thread_work(thread))
                ret = -EAGAIN;
        } else
            ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); //如果此binder事务队列栈为空且todo list为空,则挂起调用线程
    } 


Reference:

http://book.51cto.com/art/201105/265306.htm Binder驱动的实现(5)

http://www.cnblogs.com/innost/archive/2011/01/09/1931456.html Android深入浅出之Binder机制

http://home.eeworld.com.cn/my/space.php?uid=111224&do=blog&id=33723 Android的Binder机制浅析

http://hi.baidu.com/albertchen521/blog/item/822058d0f63ea2d4562c84a1.html Android IPC 通讯机制源码分析 二_albertChen的空间

Binder系列(1)——ServiceManager 1. 概述 在一台Android 8.1的手机中,能看到三个servicemanager: servicemanager,管理系统服务,本文只讨论servicemanager; vndservicemanager,管理厂商服务,对应的文件节点是/dev/vndbinder,servicemanager和vndservicemanager使用的是同一份代码,都是由service_manager.c... 阅读详情

相关推荐

ServiceManager与binder驱动的交互

文章目录ServiceManger 的初始化binder_openbinder驱动的BINDER_VERSION命令binder_become_context_managerbinder驱动的 BINDER_SET_CONTEXT_MGR命令binder_loopServiceManager loop流程binder驱动的BINDER_WRITE_READ命令binder_ioctl_write_...

三木仔 578

Windows服务程序

当这个服务需要把它当时的状态报告给SCM的时候,就必须把这个句柄传给需要它的Win32函数。像ServiceMain一样,CtrlHandler也是一个回调函数,用户必须为它的服务程序中每一个服务写一个单独的CtrlHandler函数,因此如果有一个程序含有两个服务,那么它至少要拥有5个不同的函数:作为入口点的main()或WinMain(),用于第一个服务的ServiceMain函数和CtrlHandler函数,以及用于第二个服务的ServiceMain函数和CtrlHandler函数。

始作俑者2的博客 399

Binder—从Ams注册到ServiceManager的角度来观察Binder的运行机制

目标 通过观察AMS和ServiceManager的交互来分析Binder的源代码。本文主要追的是Ams诞生出来之后通过SystemServer注册的ServiceManager这条线。并在此过程中重点学习Binder。 建议阅读以下文章: SystemServer的启动过程:https://blog.youkuaiyun.com/user11223344abc/article/details/8062...

点滴积累 1695

VC++ Service编程(二)编写ServiceMain函数

编写ServiceMain函数     下面例子中的MyServiceStart函数是这个服务的ServiceMain函数。MyServiceStart函数可以使用命令行参数,就像控制台程序中main函数那样的方式。第一个参数是传递给服务的值的个数,并且这个个数的最小值总是1。第二个参数是一个字符数组指针。数组的第一项总是当前服务的名称。     MyServiceStart函数首先填充一个S

Wang Shen 2357

Android Binder——ServiceManager初始化(六)

上一篇文章介绍到 servicemanager 的 main 函数中主要做了四件事:1)初始化 binder 驱动。2)将自身以“manager”添加到 servicemanager 中的 map 集合中。3)注册成为 binder 驱动的上下问管理者。4)给 Looper 设置 callback,进入无限循环,处理 client 端发来的请求。这里我们对其进行详细介。

小旭的专栏 622

13 Binder通信之ServiceManager

Android系统中存在很多service,当某个应用调用系统某个service的功能时,往往向系统发出请求,调用该服务的外部接口,这种外部接口我们通常叫做代理接口,也就是说要拿到目标服务需要先拿到目标服务的代理。这个时候,如果每个应用client端都向service端直接获取代理对象,势必开销很大。因此Android系统中,引入一个serviceManager的系统服务,也可以称之为Binder的守护进程来管理这些服务对象。

Johnny2004的专栏 926

VC++ Service编程(四)服务ServiceMain函数

服务ServiceMain函数     当一个服务控制程序请求开启一个新的服务时,SCM(服务控制管理器)开启服务的同时,向控制调度器发送一个开始请求。控制调度器为服务创建一个新的线程来运行ServiceMain函数。     ServiceMain函数应该执行下面的这些任务:     1、立刻为服务调用RegisterServiceCtrlHandlerEx函数,用来注册一个处理控

Wang Shen 5359

关于使用CMT2300A FIFO缓存区间设置为64Byte的问题

帮助你解决在使用CMT2300A 时遇到的各种问题,若有需要,请及时与我交流

teleger的博客 1429

Binder(三)servicemanager初始化

本文基于Android_9.0、kernel_3.18源码 由Zygote进程简介我们可以得到以下的关系图,init进程通过解析init.rc配置,启动zygote进程和service_manager进程。 service_manager初始化流程 frameworks/native/cmds/servicemanager/service_manager.c frameworks/native/cmds/servicemanager/binder.c kernel_common/drivers/andr

NIIIICO的博客 1155

告别偏色!手把手教你用i1Profiler 3.5为喷墨打印机制作专属ICC曲线(附D50/D65光源选择指南)

本文详细介绍了如何使用i1Profiler 3.5为喷墨打印机制作专属ICC曲线,解决设备偏色问题。从色彩管理基础、软件配置到色块打印与测量实战技巧,逐步指导用户完成曲线制作,并提供了D50/D65光源选择指南,确保色彩还原精准。适合摄影师和设计师提升打印质量。

weixin_30613343的博客 1万+

Benchmark系列——UnixBench测试项深度解析与性能优化指南

本文深度解析UnixBench基准测试套件的各项测试原理,包括Dhrystone、Whetstone、系统调用、进程管理、IPC及文件I/O等核心测试项。通过详细的测试项分析,指导用户解读测试报告,并提供针对性的内核参数调整、编译优化及系统配置实战指南,帮助用户精准定位并优化系统性能瓶颈。

weixin_29230901的博客 276

Binder系列2-ServiceManager

Binder系列2-ServiceManager

许浑的博客 1370

opencv的cmake报错

1、下载 ippicv_2021.8_win_intel64_20230330_general.zip、v0.1.2a.zip、opencv_videoio_ffmpeg.dll、opencv_videoio_ffmpeg_64.dll、ffmpeg_version.cmake。由于下载源在https://raw.githubusercontent.com,由于网络原因下载不顺畅,可以先找到文件下载到对应文件夹下,或者更改网络环境。ffmpeg_version.cmake文件,打开后显示如下, 另存即可。

nownow_的博客 1299

Android - Binder机制 - ServiceManager

以下几篇文章是较深入分析binder机制。 目录 1. Android - Binder机制 - ServiceManager 2. Android - Binder机制 - 普通service注册 3. Android - Binder机制 - 获得普通service 4. Android - Binder机制 - client和普通service交互 5. Android -

等等... 大雄,有啦! 4576

卫星图像检测,分割,跟踪,超分辨率,数据集调研,以及论文笔记

目标检测,针对物体有很多类如桥,烟囱,罐子等,有静态图像下的检测,也就是图像源头多来自谷歌地图,但是前后帧没有任何联系,并且谷歌地图相对来说比较清楚,难度小一点,也有粗粒度以及较细粒度的检测,然后卫星视频的数据集较少,则可以通过前后帧的联系来辅助检测,并且卫星帧基本上只对车,船,飞机,火车进行检测,没有进行细粒度的检测即将车辆分类为卡车,皮卡,小轿车,但是关船,则可以分类为货船以及军舰,因为目前的卫星视频中小车实在太少了,难以进行更细粒度的检测。luojia 三号卫星。

zhangzhao147的博客 4707

IgH EtherCAT 从入门到精通:第 30 章 实战:高可用 EtherCAT 系统设计

摘要:构建高可用EtherCAT系统的关键技术 本章详细介绍了工业级EtherCAT系统的高可用性设计方法,主要包括: 冗余链路架构:采用双网卡环形拓扑设计,主备网卡同时工作,通过IgH Master的冗余配置实现线缆故障自动切换。 状态监控机制:提供专用API实时监控主备链路状态,包括从站响应数、链路状态和冗余激活标志,形成完整的故障判断矩阵。 自动恢复功能:系统内置FSM架构支持热插拔自动检测和重配置,从站断线/重连时可自动完成状态恢复,同时允许应用层实施安全措施。 这些技术共同构成了生产环境下Ethe

从事嵌入式linux android驱动开发,拥有全栈能力 243

Android Binder详解【5】 ServiceManager

本文深入解析了Android系统中ServiceManager(SM)的核心机制。作为Binder通信的枢纽,SM采用极简设计:单线程+Looper模式处理请求,摒弃Binder线程池,通过双FD监听机制(Binder驱动FD和定时器FD)实现高效服务管理。文章详细剖析了SM的启动流程、驱动事件处理、客户端状态检测等核心功能,并以SurfaceFlinger注册为例,完整展示了从客户端请求到服务注册的Binder通信链路。SM作为Binder上下文管理器(固定句柄0)和系统服务注册表,其轻量高效的设计保障了

weixin_42065195的博客 1219

ResNet改进(45):结合通道混洗(ShuffleNet)的混合架构

本文提出了一种创新的卷积神经网络(CNN)架构CustomResNet,它将ResNet34与通道混洗(ChannelShuffle)技术相结合。该模型通过ShuffleBlock模块替换原始ResNet层,包含三个核心组件:1) ChannelShuffle模块实现通道分组混洗;2) ShuffleBlock模块整合点卷积、分组卷积和残差连接;3) CustomResNet主模型保持ResNet整体架构但替换核心层为ShuffleBlock。这种设计既保留了ResNet的残差学习能力,又通过通道混洗增强特

2401_82355416的博客 211

App 进程初始化binder、获取ServiceManager服务

数据结构 ProcessState IPCThreadState App进程启动 Init进程启动了zygote进程、system_server进程、ServiceManager进程、lwkd服务等 zygote并没有利用binder通信,而是利用socket接收信息,在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteCon...

三木仔 1043

YOLO11全网首发:CVPR2026 MixerCSeg | DEGConv方向引导边缘门控,破解细长裂缝检测难题

DEGConv通过方向先验嵌入、边缘增强卷积和动态门控三大机制,针对性解决了YOLO在处理裂缝类细长、多方向、低对比度目标时的特征提取不足问题,显著提升了裂缝检测的精度与鲁棒性。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 561

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Android 12 S ServiceManager原理

​ServiceManager是Binder通信的核心部分,提供服务注册以及查询的功能。在 Android 11 之前的版本里,它是直接使用 open、mmap、ioctl 等 api 与 binder 驱动交互。而从 Android 11 开始,ServiceManager放弃使用这些较底层的接口,转向 libbinder 库和 AIDL。

weixin_41028555的博客 4958

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Binder源码分析之ServiceManager(原)

ServiceManager作为Native层Service的管理员,有着极其重要的作用,主要表现两个方面:         1、对于服务端来说,系统所有的服务提供者都需要向ServiceManager注册。         2、对于客户端来说,所有客户端如果想要获得某个系统服务的代理,必须向ServiceManager申请相应的服务端代理。         下面从源码分析ServiceMa

阿杜的专栏 5730

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Binder通信模型 :ServiceManager

都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

2401_83642079的博客 979

从0到1学Binder-ServiceManager详解(1)

本文主要讲解servicemanager进程启动过程中ProcessState初始化,包含了binder_open,binder_ioctl等一些介绍。

weixin_41678668的博客 1385

binder驱动-ServiceManager的启动

android binder

hugh88的博客 838

Android binder学习笔记1 - 启动ServiceManager

1. 前言 本文主要是binder系列文章的总结笔记,主要是理清binder的总体流程和总体架构,期间会对照Android R进行代码重读,也会按照自己的理解对内容进行调整,以加深对binder总体的理解。本文主要讲述 启动ServiceManager。 2. ServiceManager的启动 service servicemanager /system/bin/servicemanager class core animation user system group system

HZero 1007
上一篇: Binder学习二 MediaServer
下一篇: Binder学习三 MediaServer -- 实例
cloudwu007
博客等级 码龄18年 42粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值