framework 学习笔记6. ServiceManager进
2020-12-09 本文已影响0人
加个标志位
一. ServiceManager进程是init进程解析init.rc启动的第一个服务进程,涉及到的源代码有framework/native/cmd/servicemanager目录下的 service_manager.c和binder.c ,这里的binder.c并不是binder驱动代码,而属于native层的代码;
首先进入main()方法,一共分三步:
a. 打开binder驱动;
b. 成为binder驱动管理者;
c. 循环等待处理client请求;
这三步对应的调用了framework/native/cmd/servicemanager包下的binder.c中的三个方法,详情如下:
int main(int argc, char **argv){
struct binder_state *bs;
bs = binder_open(128*1024); //a打开binder驱动;
if (!bs) {
ALOGE("failed to open binder driver\n");
return -1;
}
if (binder_become_context_manager(bs)) { //成为binder驱动管理者;
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
selinux_enabled = is_selinux_enabled();
sehandle = selinux_android_service_context_handle();
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();
}
}
union selinux_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);
svcmgr_handle = BINDER_SERVICE_MANAGER;
binder_loop(bs, svcmgr_handler); //c循环等待处理client请求;
return 0;
}
- 打开Binder驱动:binder_open(128*1024),大小为128kb;
struct binder_state *binder_open(size_t mapsize){
struct binder_state *bs;
struct binder_version vers;
bs = malloc(sizeof(*bs));
if (!bs) {
errno = ENOMEM;
return NULL;
}
//打开驱动,调用的是驱动层的binder_open()
bs->fd = open("/dev/binder", O_RDWR);
if (bs->fd < 0) {
fprintf(stderr,"binder: cannot open device (%s)\n",
strerror(errno));
goto fail_open;
}
// 获取binder驱动的版本,ioctl()==>binder_ioctl()
if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
(vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
fprintf(stderr, "binder: driver version differs from user space\n");
goto fail_open;
}
//调用的是驱动层的binder_mmap()
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;
}
return bs;
}
- 成为binder驱动管理者:binder_become_context_manager()
// 通知驱动,当前进程成为驱动层的管理者,调用的也是binder_ioctl();
int binder_become_context_manager(struct binder_state *bs){
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
- 循环等待处理client请求
void binder_loop(struct binder_state *bs, binder_handler func){
int res;
struct binder_write_read bwr; //这个结构体在笔记5中有说明
uint32_t readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
readbuf[0] = BC_ENTER_LOOPER; // BC_ENTER_LOOPER指令
binder_write(bs, readbuf, sizeof(uint32_t)); //见3.1
for (;;) { //这是一共死循环---核心代码
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
//会进入等待,如果有别的进程通过binder_ioctl()写入了数据,这里就会唤醒;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
//获取到数据后,进行解析 3.2
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;
}
}
}
3.1 framework/native/cmd/servicemanager/binder.c中的binder_write(bs, readbuf, sizeof(uint32_t))方法:
参数定义:
a. bs = binder_open(128*1024);
b. readbuf[0] = BC_ENTER_LOOPER;
c. sizeof(uint32_t) 4字节;
int binder_write(struct binder_state *bs, void *data, size_t len){
struct binder_write_read bwr;
int res;
bwr.write_size = len;
bwr.write_consumed = 0;
bwr.write_buffer = (uintptr_t) data;
//写入数据的时候,不需要读,read方面的全为0;驱动根据write_size>0写入,read_size>0读取;
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); // ioctl()方法;
if (res < 0) {
fprintf(stderr,"binder_write: ioctl failed (%s)\n",
strerror(errno));
}
return res;
}
3.2 binder_parse()方法;
uintptr_t ptr : 首地址
int binder_parse(struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func){
int r = 1;
uintptr_t end = ptr + (uintptr_t) size; // 根据首地址和size确定end;
while (ptr < end) {
// cmd命令,笔记5中有分析到,当然这里的命令不是原封不动的笔记5中的BC_TRANSACTION命令了,binder驱动会有一
//个转化===>BR_TRANSACTION
uint32_t cmd = *(uint32_t *) ptr;
ptr += sizeof(uint32_t);
switch(cmd) {
case BR_NOOP:
break;
case BR_TRANSACTION_COMPLETE:
break;
case BR_INCREFS:
case BR_ACQUIRE:
case BR_RELEASE:
case BR_DECREFS:
ptr += sizeof(struct binder_ptr_cookie);
break;
case BR_TRANSACTION: {
struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
if ((end - ptr) < sizeof(*txn)) {
ALOGE("parse: txn too small!\n");
return -1;
}
binder_dump_txn(txn);
if (func) { //这个func是回调函数,如果有,则回调回去;
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;
bio_init(&reply, rdata, sizeof(rdata), 4); // 初始化,通过binder io 来管理这一块内存;
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;
}
case BR_REPLY: {
struct binder_transaction_data *txn = (struct binder_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); //初始化,通过binder io 来管理这一块内存;
bio = 0;
} else {
/* todo FREE BUFFER */
}
ptr += sizeof(*txn);
r = 0;
break;
}
case BR_DEAD_BINDER: {
struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
ptr += sizeof(binder_uintptr_t);
death->func(bs, death->ptr);
break;
}
case BR_FAILED_REPLY:
r = -1;
break;
case BR_DEAD_REPLY:
r = -1;
break;
default:
ALOGE("parse: OOPS %d\n", cmd);
return -1;
}
}
return r;
}
回调方法分析
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply){
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
if (txn->target.handle != svcmgr_handle)
return -1;
if (txn->code == PING_TRANSACTION)
return 0;
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))) { //svcmgr_id是android.os.iservicemanager
fprintf(stderr,"invalid id %s\n", str8(s, len));
return -1; //如果不是传给iservicemanager,则返回
}
if (sehandle && selinux_status_updated() > 0) {
struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
if (tmp_sehandle) {
selabel_close(sehandle);
sehandle = tmp_sehandle;
}
}
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_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);
return 0;
case SVC_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;
//do_add_service()中的sender_pid是pid_t,用来检验权限
if (do_add_service(bs, s, len, handle, txn->sender_euid,allow_isolated, txn->sender_pid))
return -1;
break;
case SVC_MGR_LIST_SERVICES: {
uint32_t n = 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);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
servicemanager.PNG