- 論壇徽章:
- 0
|
第一部分Binder的組成
1.1
驅(qū)動(dòng)
程序部分驅(qū)動(dòng)程序的部分在以下的文件夾中:
kernel/include/linux/binder.h
kernel/drivers/android/binder.c
binder驅(qū)動(dòng)程序是一個(gè)miscdevice,主設(shè)備號(hào)為10,此設(shè)備號(hào)使用動(dòng)態(tài)獲得(MISC_DYNAMIC_MINOR),其設(shè)備的節(jié)點(diǎn)為:
/dev/binder
binder驅(qū)動(dòng)程序會(huì)在proc文件系統(tǒng)中建立自己的信息,其文件夾為/proc/binde,其中包含如下內(nèi)容:
proc目錄:調(diào)用Binder各個(gè)進(jìn)程的內(nèi)容
state文件:使用函數(shù)binder_read_proc_state
stats文件:使用函數(shù)binder_read_proc_stats
transactions文件:使用函數(shù)binder_read_proc_transactions
transaction_log文件:使用函數(shù)binder_read_proc_transaction_log,其參數(shù)為binder_transaction_log (類型為struct binder_transaction_log)
failed_transaction_log文件:使用函數(shù)binder_read_proc_transaction_log 其參數(shù)為
binder_transaction_log_failed (類型為struct binder_transaction_log)
在binder文件被打開后,其私有數(shù)據(jù)(private_data)的類型:
struct binder_proc
在這個(gè)數(shù)據(jù)結(jié)構(gòu)中,主要包含了當(dāng)前進(jìn)程、進(jìn)程ID、
內(nèi)存
映射信息、Binder的統(tǒng)計(jì)信息和線程信息等。
在用戶空間對(duì)Binder驅(qū)動(dòng)程序進(jìn)行控制主要使用的接口是mmap、poll和ioctl,ioctl主要使用的ID為:
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t)
#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t)
#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int)
#define BINDER_THREAD_EXIT _IOW('b', 8, int)
#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
BR_XXX等宏為BinderDriverReturnProtocol,表示Binder驅(qū)動(dòng)返回協(xié)議。
BC_XXX等宏為BinderDriverCommandProtocol,表示Binder驅(qū)動(dòng)命令協(xié)議。
binder_thread是Binder驅(qū)動(dòng)程序中使用的另外一個(gè)重要的數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu)的定義如下所示:
struct binder_thread {
struct binder_proc *proc;
struct rb_node rb_node;
int pid;
int looper;
struct binder_transaction *transaction_stack;
struct list_head todo;
uint32_t return_error;
uint32_t return_error2;
wait_queue_head_t wait;
struct binder_stats stats;
};
binder_thread 的各個(gè)成員信息是從rb_node中得出。
BINDER_WRITE_READ是最重要的ioctl,它使用一個(gè)數(shù)據(jù)結(jié)構(gòu)binder_write_read定義讀寫的數(shù)據(jù)。
struct binder_write_read {
signed long write_size;
signed long write_consumed;
unsigned long write_buffer;
signed long read_size;
signed long read_consumed;
unsigned long read_buffer;
};
1.3 binder的庫(kù)的部分
binder相關(guān)的文件作為Android的uitls庫(kù)的一部分,這個(gè)庫(kù)編譯后的名稱為libutils.so,是Android系統(tǒng)中的一個(gè)公共庫(kù)。
主要文件的路徑如下所示:
frameworks/base/include/utils/*
frameworks/base/libs/utils/*
主要的類為:
RefBase.h :
引用計(jì)數(shù),定義類RefBase。
Parcel.h :
為在IPC中傳輸?shù)臄?shù)據(jù)定義容器,定義類Parcel
IBinder.h:
Binder對(duì)象的抽象接口, 定義類IBinder
Binder.h:
Binder對(duì)象的基本功能, 定義類Binder和BpRefBase
BpBinder.h:
BpBinder的功能,定義類BpBinder
IInterface.h:
為抽象經(jīng)過Binder的接口定義通用類,
定義類IInterface,類模板BnInterface,類模板BpInterface
ProcessState.h
表示進(jìn)程狀態(tài)的類,定義類ProcessState
IPCThreadState.h
表示IPC線程的狀態(tài),定義類IPCThreadState
各個(gè)類之間的關(guān)系如下所示:
![]()
1.2 servicemanager部分 servicemanager是一個(gè)守護(hù)進(jìn)程,用于這個(gè)進(jìn)程的和/dev/binder通訊,從而達(dá)到管理系統(tǒng)中各個(gè)服務(wù)的作用。
可執(zhí)行程序的路徑:
/system/bin/servicemanager
開源版本文件的路徑:
frameworks/base/cmds/servicemanager/binder.h
frameworks/base/cmds/servicemanager/binder.c
frameworks/base/cmds/servicemanager/service_manager.c
程序執(zhí)行的流程:
open():打開binder驅(qū)動(dòng)
mmap():映射一個(gè)128*1024字節(jié)的內(nèi)存
ioctl(BINDER_SET_CONTEXT_MGR):設(shè)置上下文為mgr
進(jìn)入主循環(huán)binder_loop()
ioctl(BINDER_WRITE_READ),讀取
binder_parse()進(jìn)入binder處理過程循環(huán)處理
binder_parse()的處理,調(diào)用返回值:
當(dāng)處理BR_TRANSACTION的時(shí)候,調(diào)用svcmgr_handler()處理增加服務(wù)、檢查服務(wù)等工作。各種服務(wù)存放在一個(gè)鏈表(svclist)中。其中調(diào)用binder_等開頭的函數(shù),又會(huì)調(diào)用ioctl的各種命令。
處理BR_REPLY的時(shí)候,填充binder_io類型的數(shù)據(jù)結(jié)
第二部分 Binder的運(yùn)作
2.1 Binder的工作機(jī)制
Service Manager是一個(gè)守護(hù)進(jìn)程,它負(fù)責(zé)啟動(dòng)各個(gè)進(jìn)程之間的服務(wù),對(duì)于相關(guān)的兩個(gè)需要通訊的進(jìn)程,它們通過調(diào)用libutil.so庫(kù)實(shí)現(xiàn)通訊,而真正通訊的機(jī)制,是內(nèi)核空間中的一塊共享
內(nèi)存
。
![]()
2.2 從應(yīng) 用程序的角度看Binder
從應(yīng)用程序的角度看Binder一共有三個(gè)方面:
Native 本地:例如BnABC,這是一個(gè)需要被繼承和實(shí)現(xiàn)的類。
Proxy 代理:例如BpABC,這是一個(gè)在接口框架中被實(shí)現(xiàn),但是在接口中沒有體現(xiàn)的類。
客戶端:例如客戶端得到一個(gè)接口ABC,在調(diào)用的時(shí)候?qū)嶋H上被調(diào)用的是BpABC
![]()
本地功能(Bn)部分做的:
實(shí)現(xiàn)BnABC:: BnTransact()
注冊(cè)服務(wù):IServiceManager::AddService
代理部分(Bp)做的:
實(shí)現(xiàn)幾個(gè)功能函數(shù),調(diào)用BpABC::remote()->transact()
客戶端做的:
獲得ABC接口,然后調(diào)用接口(實(shí)際上調(diào)用了BpABC,繼而通過IPC調(diào)用了BnABC,然后調(diào)用了具體的功能)
在程序的實(shí)現(xiàn)過程中BnABC和BpABC是雙繼承了接口ABC。一般來(lái)說(shuō)BpABC是一個(gè)實(shí)現(xiàn)類,這個(gè)實(shí)現(xiàn)類不需要在接口中體現(xiàn),它實(shí)際上負(fù)責(zé)的只是通訊功能,不執(zhí)行具體的功能;BnABC則是一個(gè)接口類,需要一個(gè)真正工作的類來(lái)繼承、實(shí)現(xiàn)它,這個(gè)類才是真正執(zhí)行具體功能的類。
在客戶端中,從ISeriviceManager中獲得一個(gè)ABC的接口,客戶端調(diào)用這個(gè)接口,實(shí)際上是在調(diào)用BpABC,而BpABC又通過Binder的IPC機(jī)制和BnABC通訊,BnABC的實(shí)現(xiàn)類在后面執(zhí)行。
事實(shí)上,
服務(wù)器
的具體實(shí)現(xiàn)和客戶端是兩個(gè)不同的進(jìn)程,如果不考慮進(jìn)程間通訊的過程,從調(diào)用者的角度,似乎客戶端在直接調(diào)用另外一個(gè)進(jìn)程間的函數(shù)——當(dāng)然這個(gè)函數(shù)必須是接口ABC中定義的。
2.3 ISericeManager的作用
ISericeManager涉及的兩個(gè)文件是ISericeManager.h和ISericeManager.cpp。這兩個(gè)文件基本上是 ISericeManager。ISericeManager是系統(tǒng)最先被啟動(dòng)的服務(wù)。非常值得注意的是:ISericeManager本地功能并沒有使現(xiàn),它實(shí)際上由ServiceManager守護(hù)進(jìn)程執(zhí)行,而用戶程序通過調(diào)用BpServiceManager來(lái)獲得其他的服務(wù)。
在ISericeManager.h中定義了一個(gè)接口,用于得到默認(rèn)的ISericeManager:
sp defaultServiceManager();
這時(shí)得到的ISericeManager實(shí)際上是一個(gè)全局的ISericeManager
第三部分 程序中Binder的具體實(shí)現(xiàn)
3.1 一個(gè)利用接口的具體實(shí)現(xiàn)
PermissionController也是libutils中定義的一個(gè)有關(guān)權(quán)限控制的接口,它一共包含兩個(gè)文件:IPermissionController.h和IPermissionController.cpp這個(gè)結(jié)構(gòu)在所有類的實(shí)現(xiàn)中都是類似的。
頭文件IPermissionController.h的主要內(nèi)容是定義IPermissionController接口和類BnPermissionController:
class IPermissionController : public IInterface
{
public:
DECLARE_META_INTERFACE(PermissionController);
virtual bool checkPermission(const String16& permission,int32_t pid, int32_t uid) = 0;
enum {
CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION
};
};
class BnPermissionController : public BnInterface
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
IPermissionController是一個(gè)接口類,只有checkPermission()一個(gè)純虛函數(shù)。
BnPermissionController繼承了以BnPermissionController實(shí)例化模版類BnInterface。因此,BnPermissionController,事實(shí)上BnPermissionController雙繼承了BBinder和 IPermissionController。
實(shí)現(xiàn)文件IPermissionController.cpp中,首先實(shí)現(xiàn)了一個(gè)BpPermissionController。
class BpPermissionController : public BpInterface
{
public:
BpPermissionController(const sp& impl)
: BpInterface(impl)
{
}
virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
{
Parcel data, reply;
data.writeInterfaceToken(IPermissionController::
getInterfaceDescriptor());
data.writeString16(permission);
data.writeInt32(pid);
data.writeInt32(uid);
remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
if (reply.readInt32() != 0) return 0;
return reply.readInt32() != 0;
}
};
IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
BpPermissionController繼承了BpInterface,它本身是一個(gè)已經(jīng)實(shí)現(xiàn)的類,而且并沒有在接口中體現(xiàn)。這個(gè)類按照格式寫就可以,在實(shí)現(xiàn)checkPermission()函數(shù)的過程中,使用Parcel作為傳輸數(shù)據(jù)的容器,傳輸中時(shí)候transact()函數(shù),其參數(shù)需要包含枚舉值CHECK_PERMISSION_TRANSACTION。 IMPLEMENT_META_INTERFACE用于扶助生成。
BnPermissionController中實(shí)現(xiàn)的onTransact()函數(shù)如下所示:
status_t BnPermissionController:: BnTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CHECK_PERMISSION_TRANSACTION: {
CHECK_INTERFACE(IPermissionController, data, reply);
String16 permission = data.readString16();
int32_t pid = data.readInt32();
int32_t uid = data.readInt32();
bool res = checkPermission(permission, pid, uid);
reply->writeInt32(0);
reply->writeInt32(res ? 1 : 0);
return NO_ERROR;
} break;
default:
return BBinder:: BnTransact(code, data, reply, flags);
}
}
在onTransact()函數(shù)中根據(jù)枚舉值判斷數(shù)據(jù)使用的方式。注意,由于BnPermissionController也是繼承了類 IPermissionController,但是純虛函數(shù)checkPermission()依然沒有實(shí)現(xiàn)。因此這個(gè) BnPermissionController類并不能實(shí)例化,它其實(shí)也還是一個(gè)接口,需要一個(gè)實(shí)現(xiàn)類來(lái)繼承它,那才是實(shí)現(xiàn)具體功能的類。
3.2 BnABC的實(shí)現(xiàn)
本地服務(wù)啟動(dòng)后將形成一個(gè)守護(hù)進(jìn)程,具體的本地服務(wù)是由一個(gè)實(shí)現(xiàn)類繼承BnABC來(lái)實(shí)現(xiàn)的,這個(gè)服務(wù)的名稱通常叫做ABC。
在其中,通常包含了一個(gè)instantiate()函數(shù),這個(gè)函數(shù)一般按照如下的方式實(shí)現(xiàn):
void ABC::instantiate() {
defaultServiceManager()->addService(
String16("XXX.ABC"), new ABC ());
}
按照這種方式,通過調(diào)用defaultServiceManager()函數(shù),將增加一個(gè)名為"XXX.ABC"的服務(wù)。
在這個(gè)defaultServiceManager()函數(shù)中調(diào)用了:
ProcessState::self()->getContextObject(NULL));
IPCThreadState* ipc = IPCThreadState::self();
IPCThreadState::talkWithDriver()
在ProcessState 類建立的過程中調(diào)用open_driver()打開
驅(qū)動(dòng)
程序,在talkWithDriver()的執(zhí)行過程中。
3.3 BpABC調(diào)用的實(shí)現(xiàn)
BpABC調(diào)用的過程主要通過mRemote()->transact() 來(lái)傳輸數(shù)據(jù),mRemote()是BpRefBase的成員,它是一個(gè)IBinder。這個(gè)調(diào)用過程如下所示:
mRemote()->transact()
Process::self()
IPCThreadState::self()->transact()
writeTransactionData()
waitForResponse()
talkWithDriver()
ioctl(fd, BINDER_WRITE_READ, &bwr)
在IPCThreadState::executeCommand()函數(shù)中,實(shí)現(xiàn)傳輸操作
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u2/85805/showart_2093407.html |
|