news 2026/5/25 21:10:21

Android Framework P4 - ServiceManager 进程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android Framework P4 - ServiceManager 进程

ServiceManager 进程

// /system/core/rootdir/init.rc service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
// /frameworks/native/cmds/servicemanager/service_manager.cintmain(intargc,char**argv){structbinder_state*bs;bs=binder_open(128*1024);if(!bs){ALOGE("failed to open binder driver\n");return-1;}if(binder_become_context_manager(bs)){ALOGE("cannot become context manager (%s)\n",strerror(errno));return-1;}selinux_enabled=is_selinux_enabled();sehandle=selinux_android_service_context_handle();selinux_status_open(true);if(selinux_enabled>0){if(sehandle==NULL){ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");abort();}if(getcon(&service_manager_context)!=0){ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");abort();}}unionselinux_callback cb;cb.func_audit=audit_callback;selinux_set_callback(SELINUX_CB_AUDIT,cb);cb.func_log=selinux_log_callback;selinux_set_callback(SELINUX_CB_LOG,cb);binder_loop(bs,svcmgr_handler);return0;}
// /frameworks/native/cmds/servicemanager/binder.cstructbinder_state*binder_open(size_tmapsize){structbinder_state*bs;structbinder_versionvers;bs=malloc(sizeof(*bs));if(!bs){errno=ENOMEM;returnNULL;}bs->fd=open("/dev/binder",O_RDWR);if(bs->fd<0){fprintf(stderr,"binder: cannot open device (%s)\n",strerror(errno));gotofail_open;}if((ioctl(bs->fd,BINDER_VERSION,&vers)==-1)||(vers.protocol_version!=BINDER_CURRENT_PROTOCOL_VERSION)){fprintf(stderr,"binder: kernel driver version (%d) differs from user space version (%d)\n",vers.protocol_version,BINDER_CURRENT_PROTOCOL_VERSION);gotofail_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));gotofail_map;}returnbs;fail_map:close(bs->fd);fail_open:free(bs);returnNULL;}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_become_context_manager(structbinder_state*bs){returnioctl(bs->fd,BINDER_SET_CONTEXT_MGR,0);}
// /frameworks/native/cmds/servicemanager/binder.cvoidbinder_loop(structbinder_state*bs,binder_handler func){intres;structbinder_write_readbwr;uint32_treadbuf[32];bwr.write_size=0;bwr.write_consumed=0;bwr.write_buffer=0;readbuf[0]=BC_ENTER_LOOPER;binder_write(bs,readbuf,sizeof(uint32_t));for(;;){bwr.read_size=sizeof(readbuf);bwr.read_consumed=0;bwr.read_buffer=(uintptr_t)readbuf;res=ioctl(bs->fd,BINDER_WRITE_READ,&bwr);if(res<0){ALOGE("binder_loop: ioctl failed (%s)\n",strerror(errno));break;}res=binder_parse(bs,0,(uintptr_t)readbuf,bwr.read_consumed,func);if(res==0){ALOGE("binder_loop: unexpected reply?!\n");break;}if(res<0){ALOGE("binder_loop: io error %d %s\n",res,strerror(errno));break;}}}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_parse(structbinder_state*bs,structbinder_io*bio,uintptr_tptr,size_tsize,binder_handler func){intr=1;uintptr_tend=ptr+(uintptr_t)size;while(ptr<end){uint32_tcmd=*(uint32_t*)ptr;ptr+=sizeof(uint32_t);#ifTRACEfprintf(stderr,"%s:\n",cmd_name(cmd));#endifswitch(cmd){caseBR_NOOP:break;caseBR_TRANSACTION_COMPLETE:break;caseBR_INCREFS:caseBR_ACQUIRE:caseBR_RELEASE:caseBR_DECREFS:#ifTRACEfprintf(stderr," %p, %p\n",(void*)ptr,(void*)(ptr+sizeof(void*)));#endifptr+=sizeof(structbinder_ptr_cookie);break;caseBR_TRANSACTION:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("parse: txn too small!\n");return-1;}binder_dump_txn(txn);if(func){unsignedrdata[256/4];structbinder_iomsg;structbinder_ioreply;intres;bio_init(&reply,rdata,sizeof(rdata),4);bio_init_from_txn(&msg,txn);res=func(bs,txn,&msg,&reply);binder_send_reply(bs,&reply,txn->data.ptr.buffer,res);}ptr+=sizeof(*txn);break;}caseBR_REPLY:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("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);r=0;break;}caseBR_DEAD_BINDER:{structbinder_death*death=(structbinder_death*)(uintptr_t)*(binder_uintptr_t*)ptr;ptr+=sizeof(binder_uintptr_t);death->func(bs,death->ptr);break;}caseBR_FAILED_REPLY:r=-1;break;caseBR_DEAD_REPLY:r=-1;break;default:ALOGE("parse: OOPS %d\n",cmd);return-1;}}returnr;}
// /frameworks/native/cmds/servicemanager/service_manager.cintsvcmgr_handler(structbinder_state*bs,structbinder_transaction_data*txn,structbinder_io*msg,structbinder_io*reply){structsvcinfo*si;uint16_t*s;size_tlen;uint32_thandle;uint32_tstrict_policy;intallow_isolated;//ALOGI("target=%p code=%d pid=%d uid=%d\n",// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);if(txn->target.ptr!=BINDER_SERVICE_MANAGER)return-1;if(txn->code==PING_TRANSACTION)return0;// Equivalent to Parcel::enforceInterface(), reading the RPC// header with the strict mode policy mask and the interface name.// Note that we ignore the strict_policy and don't propagate it// further (since we do no outbound RPCs anyway).strict_policy=bio_get_uint32(msg);s=bio_get_string16(msg,&len);if(s==NULL){return-1;}if((len!=(sizeof(svcmgr_id)/2))||memcmp(svcmgr_id,s,sizeof(svcmgr_id))){fprintf(stderr,"invalid id %s\n",str8(s,len));return-1;}if(sehandle&&selinux_status_updated()>0){structselabel_handle*tmp_sehandle=selinux_android_service_context_handle();if(tmp_sehandle){selabel_close(sehandle);sehandle=tmp_sehandle;}}switch(txn->code){caseSVC_MGR_GET_SERVICE:caseSVC_MGR_CHECK_SERVICE:s=bio_get_string16(msg,&len);if(s==NULL){return-1;}handle=do_find_service(bs,s,len,txn->sender_euid,txn->sender_pid);if(!handle)break;bio_put_ref(reply,handle);return0;caseSVC_MGR_ADD_SERVICE:s=bio_get_string16(msg,&len);if(s==NULL){return-1;}handle=bio_get_ref(msg);allow_isolated=bio_get_uint32(msg)?1:0;if(do_add_service(bs,s,len,handle,txn->sender_euid,allow_isolated,txn->sender_pid))return-1;break;caseSVC_MGR_LIST_SERVICES:{uint32_tn=bio_get_uint32(msg);if(!svc_can_list(txn->sender_pid)){ALOGE("list_service() uid=%d - PERMISSION DENIED\n",txn->sender_euid);return-1;}si=svclist;while((n-->0)&&si)si=si->next;if(si){bio_put_string16(reply,si->name);return0;}return-1;}default:ALOGE("unknown code %d\n",txn->code);return-1;}bio_put_uint32(reply,0);return0;}
// /frameworks/native/cmds/servicemanager/service_manager.cintdo_add_service(structbinder_state*bs,constuint16_t*s,size_tlen,uint32_thandle,uid_tuid,intallow_isolated,pid_tspid){structsvcinfo*si;//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);if(!handle||(len==0)||(len>127))return-1;if(!svc_can_register(s,len,spid)){ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",str8(s,len),handle,uid);return-1;}si=find_svc(s,len);if(si){if(si->handle){ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",str8(s,len),handle,uid);svcinfo_death(bs,si);}si->handle=handle;}else{si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));if(!si){ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",str8(s,len),handle,uid);return-1;}si->handle=handle;si->len=len;memcpy(si->name,s,(len+1)*sizeof(uint16_t));si->name[len]='\0';si->death.func=(void*)svcinfo_death;si->death.ptr=si;si->allow_isolated=allow_isolated;si->next=svclist;svclist=si;}binder_acquire(bs,handle);binder_link_to_death(bs,handle,&si->death);return0;}
  1. binder_open(128*1024):打开 Binder 驱动

    • open("/dev/binder", O_RDWR):打开/dev/binder

    • 检查驱动版本:ioctl(bs->fd, BINDER_VERSION, &vers)获取驱动版本,vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION对比版本

    • mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0):内存映射

    • return bs:返回句柄

  2. binder_become_context_manager(bs):成为上下文管理器,固定编号 0

  3. binder_loop(bs, svcmgr_handler):进入 Binder 循环,处理所有请求

    • binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func):解析数据

      • switch(cmd):处理业务
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 21:10:12

长期使用Taotoken聚合接口对项目运维复杂度的实际影响观察

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期使用Taotoken聚合接口对项目运维复杂度的实际影响观察 在过去的几个月里&#xff0c;我们团队的一个核心项目持续通过Taotoken…

作者头像 李华
网站建设 2026/5/25 21:10:01

2026小白必看!6大高薪AI岗位,0基础也能轻松入坑,月薪直冲40K!

2026年AI行业人才缺口将达400万&#xff0c;其中提示词工程师、AI训练师等6大岗位对零基础者极为友好&#xff0c;无需深厚算法/编程背景。文章详细介绍了这些岗位的职责、要求及薪资范围&#xff0c;并建议小白优先选择无代码/低代码岗位&#xff0c;同时考取相关证书可提升就…

作者头像 李华
网站建设 2026/5/25 21:09:17

突发!AI入侵电网控制系统,美国电力公司紧急修复漏洞

凌晨3点的警报 2026年5月20日凌晨3:17,美国中西部某大型电力公司的安全监控中心突然响起警报。 系统显示,位于堪萨斯州的一个电网控制节点出现异常数据访问。安全团队立即启动应急响应,在2小时内成功阻止了一次潜在的大规模停电事件。 攻击手法分析 根据事后调查,攻击者…

作者头像 李华
网站建设 2026/5/25 21:08:45

低成本四足机器人定位新思路:给Go1狗腿装上MPU9250 IMU,实测漂移降低80%

低成本四足机器人定位优化实战&#xff1a;MPU9250 IMU改造与EKF算法融合 四足机器人的定位精度一直是制约其实际应用的关键瓶颈。传统消费级和教育级机器狗如宇树Go1&#xff0c;往往因成本限制无法配备昂贵的激光雷达或视觉系统&#xff0c;导致在复杂环境中的定位漂移问题突…

作者头像 李华