Android10啟動(dòng)之servicemanager源碼解析_第1頁(yè)
Android10啟動(dòng)之servicemanager源碼解析_第2頁(yè)
Android10啟動(dòng)之servicemanager源碼解析_第3頁(yè)
Android10啟動(dòng)之servicemanager源碼解析_第4頁(yè)
Android10啟動(dòng)之servicemanager源碼解析_第5頁(yè)
已閱讀5頁(yè),還剩5頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論