




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Android10啟動(dòng)之servicemanager源碼解析目錄正文獲取服務(wù)注冊(cè)服務(wù)
正文
上一篇文章:
Android10啟動(dòng)分析之Init篇(一)
在前文提到,init進(jìn)程會(huì)在在Trigger為init的Action中,啟動(dòng)servicemanager服務(wù),這篇文章我們就來(lái)具體分析一下servicemanager服務(wù),它到底做了哪些事情。
servicemanager服務(wù)的源碼位于/frameworks/native/cmds/servicemanager/service_manager.c,我們將從這個(gè)類的入口開(kāi)始看起。
intmain(intargc,char**argv)
structbinder_state*bs;
unionselinux_callbackcb;
char*driver;
if(argc1){
driver=argv[1];
}else{
//啟動(dòng)時(shí)默認(rèn)無(wú)參數(shù),走這個(gè)分支
driver="/dev/binder";
//打開(kāi)binder驅(qū)動(dòng),并設(shè)置mmap的內(nèi)存大小為128k
bs=binder_open(driver,128*1024);
if(binder_become_context_manager(bs)){
ALOGE("cannotbecomecontextmanager(%s)\n",strerror(errno));
return-1;
cb.func_audit=audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT,cb);
#ifdefVENDORSERVICEMANAGER
cb.func_log=selinux_vendor_log_callback;
#else
cb.func_log=selinux_log_callback;
#endif
selinux_set_callback(SELINUX_CB_LOG,cb);
#ifdefVENDORSERVICEMANAGER
sehandle=selinux_android_vendor_service_context_handle();
#else
sehandle=selinux_android_service_context_handle();
#endif
selinux_status_open(true);
if(sehandle==NULL){
ALOGE("SELinux:Failedtoacquiresehandle.Aborting.\n");
abort();
if(getcon(service_manager_context)!=0){
ALOGE("SELinux:Failedtoacquireservice_managercontext.Aborting.\n");
abort();
/*binder_loop已封裝如下步驟:
while(1)
/*readdata*/
/*parsedata,andprocess*/
/*reply*/
binder_loop(bs,svcmgr_handler);
return0;
從main函數(shù)中可以看出,它主要做了三件事情:
打開(kāi)/dev/binder設(shè)備,并在內(nèi)存中映射128K的空間。通知Binder設(shè)備,把自己變成context_manager,其他用戶進(jìn)程都通過(guò)0號(hào)句柄訪問(wèn)ServiceManager。進(jìn)入循環(huán),不停的去讀Binder設(shè)備,看是否有對(duì)service的請(qǐng)求,如果有的話,就去調(diào)用svcmgr_handler函數(shù)回調(diào)處理請(qǐng)求。
我們?cè)賮?lái)看看svcmgr_handler函數(shù)的實(shí)現(xiàn):
intsvcmgr_handler(structbinder_state*bs,
structbinder_transaction_data_secctx*txn_secctx,
structbinder_io*msg,
structbinder_io*reply)
structsvcinfo*si;
uint16_t*s;
size_tlen;
uint32_thandle;
uint32_tstrict_policy;
intallow_isolated;
uint32_tdumpsys_priority;
structbinder_transaction_data*txn=txn_secctx-transaction_data;
if(txn-target.ptr!=BINDER_SERVICE_MANAGER)
return-1;
if(txn-code==PING_TRANSACTION)
return0;
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(s,len,txn-sender_euid,txn-sender_pid,
(constchar*)txn_secctx-secctx);
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;
dumpsys_priority=bio_get_uint32(msg);
if(do_add_service(bs,s,len,handle,txn-sender_euid,allow_isolated,dumpsys_priority,
txn-sender_pid,(constchar*)txn_secctx-secctx))
return-1;
break;
caseSVC_MGR_LIST_SERVICES:{
uint32_tn=bio_get_uint32(msg);
uint32_treq_dumpsys_priority=bio_get_uint32(msg);
if(!svc_can_list(txn-sender_pid,(constchar*)txn_secctx-secctx,txn-sender_euid)){
ALOGE("list_service()uid=%d-PERMISSIONDENIED\n",
txn-sender_euid);
return-1;
si=svclist;
//walkthroughthelistofservicesntimesskippingservicesthat
//donotsupporttherequestedpriority
while(si){
if(si-dumpsys_priorityreq_dumpsys_priority){
if(n==0)break;
n--;
si=si-next;
if(si){
bio_put_string16(reply,si-name);
return0;
return-1;
default:
ALOGE("unknowncode%d\n",txn-code);
return-1;
bio_put_uint32(reply,0);
return0;
我們先來(lái)認(rèn)識(shí)一下binder的數(shù)據(jù)傳輸載體binder_transaction_data:
structbinder_transaction_data{
union{
/*當(dāng)binder_transaction_data是由用戶空間的進(jìn)程發(fā)送給Binder驅(qū)動(dòng)時(shí),
handle是該事務(wù)的發(fā)送目標(biāo)在Binder驅(qū)動(dòng)中的信息,即該事務(wù)會(huì)交給handle來(lái)處理;
handle的值是目標(biāo)在Binder驅(qū)動(dòng)中的Binder引用。*/
__u32handle;
/*當(dāng)binder_transaction_data是有Binder驅(qū)動(dòng)反饋給用戶空間進(jìn)程時(shí),
ptr是該事務(wù)的發(fā)送目標(biāo)在用戶空間中的信息,即該事務(wù)會(huì)交給ptr對(duì)應(yīng)的服務(wù)來(lái)處理;
ptr是處理該事務(wù)的服務(wù)的服務(wù)在用戶空間的本地Binder對(duì)象。*/
binder_uintptr_tptr;
}target;//該事務(wù)的目標(biāo)對(duì)象(即,該事務(wù)數(shù)據(jù)包是給該target來(lái)處理的)
//只有當(dāng)事務(wù)是由Binder驅(qū)動(dòng)傳遞給用戶空間時(shí),cookie才有意思,它的值是處理該事務(wù)的ServerC++層的本地Binder對(duì)象
binder_uintptr_tcookie;
//事務(wù)編碼。如果是請(qǐng)求,則以BC_開(kāi)頭;如果是回復(fù),則以BR_開(kāi)頭。
__u32code;
/*Generalinformationaboutthetransaction.*/
__u32flags;
//表示事務(wù)發(fā)起者的pid和uid。
pid_tsender_pid;
uid_tsender_euid;
//數(shù)據(jù)大小
binder_size_tdata_size;
//數(shù)據(jù)偏移量
binder_size_toffsets_size;
//data是一個(gè)共用體,當(dāng)通訊數(shù)據(jù)很小的時(shí),可以直接使用buf[8]來(lái)保存數(shù)據(jù)。當(dāng)夠大時(shí),只能用指針buffer來(lái)描述一個(gè)申請(qǐng)的數(shù)據(jù)緩沖區(qū)。
union{
struct{
/*transactiondata*/
binder_uintptr_tbuffer;
binder_uintptr_toffsets;
}ptr;
__u8buf[8];
}data;
可以看到,svcmgr_handler函數(shù)中對(duì)binderdata的事務(wù)編碼進(jìn)行了判斷,并分別對(duì)SVC_MGR_GET_SERVICE(SVC_MGR_CHECK_SERVICE)、SVC_MGR_ADD_SERVICE、SVC_MGR_LIST_SERVICES三種類型的事務(wù)編碼做了業(yè)務(wù)處理。
獲取服務(wù)
caseSVC_MGR_CHECK_SERVICE:
s=bio_get_string16(msg,len);
ptr=do_find_service(bs,s,len);
if(!ptr)
break;
bio_put_ref(reply,ptr);
return0;
do_find_service函數(shù)中主要執(zhí)行service的查找,并把找到的服務(wù)句柄寫入reply,返回給客戶端。
uint32_tdo_find_service(constuint16_t*s,size_tlen,uid_tuid,pid_tspid,constchar*sid)
structsvcinfo*si=find_svc(s,len);
returnsi-handle;
我們繼續(xù)看find_svc函數(shù):
structsvcinfo*find_svc(constuint16_t*s16,size_tlen)
structsvcinfo*si;
for(si=svclist;si;si=si-next){
if((len==si-len)
!memcmp(s16,si-name,len*sizeof(uint16_t))){
returnsi;
returnNULL;
svclist是一個(gè)單向鏈表,儲(chǔ)存了所有向servicemanager注冊(cè)的服務(wù)信息。find_svc遍歷svclist鏈表,通過(guò)服務(wù)名稱作為索引條件,最終找到符合條件的服務(wù)。
注冊(cè)服務(wù)
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;
dumpsys_priority=bio_get_uint32(msg);
if(do_add_service(bs,s,len,handle,txn-sender_euid,allow_isolated,dumpsys_priority,
txn-sender_pid,(constchar*)txn_secctx-secctx))
return-1;
我們繼續(xù)看do_add_service函數(shù)中做了哪些事情。
在該函數(shù)中,首先會(huì)去檢查客戶端是否有權(quán)限注冊(cè)service,如果沒(méi)有權(quán)限就直接返回,不能注冊(cè)。
if(!svc_can_register(s,len,spid,sid,uid)){
ALOGE("add_service('%s',%x)uid=%d-PERMISSIONDENIED\n",
str8(s,len),handle,uid);
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)療安全文化的培育與實(shí)踐案例
- 醫(yī)療用品供應(yīng)鏈金融中區(qū)塊鏈技術(shù)的應(yīng)用與探索
- 醫(yī)療數(shù)據(jù)管理與分析技術(shù)
- 醫(yī)療領(lǐng)域中的區(qū)塊鏈版權(quán)保護(hù)技術(shù)應(yīng)用
- 醫(yī)療AI應(yīng)用在醫(yī)學(xué)影像診斷中的市場(chǎng)分析
- 2025屆安徽合肥市七年級(jí)生物第二學(xué)期期末學(xué)業(yè)質(zhì)量監(jiān)測(cè)試題含解析
- 2025屆遼寧省大連協(xié)作學(xué)校生物七下期末統(tǒng)考模擬試題含解析
- LSRIQA2-013.A0矯正與預(yù)防措施程序
- 醫(yī)療衛(wèi)生的未來(lái)公共衛(wèi)生勞動(dòng)教育的探索與展望
- 區(qū)塊鏈技術(shù)在醫(yī)療信息互操作性的實(shí)踐
- 國(guó)際機(jī)票基礎(chǔ)知識(shí)培訓(xùn)課件
- 蒸汽疏水器原理及簡(jiǎn)介課件
- 部編版語(yǔ)文四年級(jí)下冊(cè)第六單元 復(fù)習(xí)課件
- 蒸汽暖管方案
- DB12-474-2012公用紡織產(chǎn)品通用技術(shù)要求
- 基礎(chǔ)會(huì)計(jì)課件(完整版)
- 管理者的職業(yè)素養(yǎng)及能力
- 2022年國(guó)企集團(tuán)公司職工代表大會(huì)制度國(guó)企職工代表大會(huì)提案
- 國(guó)家開(kāi)放大學(xué)計(jì)算機(jī)應(yīng)用基礎(chǔ)(本) 終結(jié)性考試試題及參考答案
- 《 煉油化工建設(shè)項(xiàng)目后評(píng)價(jià)報(bào)告 》
- 王澤鑒教授:請(qǐng)求權(quán)基礎(chǔ)、法學(xué)方法與民法發(fā)展(修改版20141028)
評(píng)論
0/150
提交評(píng)論