Links to related articles:
1. Android Framework – Learning Launcher
2. Adding process of Android Binder driving-Media service
3. Android Binder driver – Start the ServiceManager process
Android Binder driver – kernel driver layer source code analysis
5. Android Binder drivers – Analyze the service addition process from the driver layer
6. Android Binder driver – Track service searches from the Java layer
Related source files:
/system/core/rootdir/init.rc
/frameworks/native/cmds/servicemanager/service_manager.c
/frameworks/native/cmds/servicemanager/binder.c
Copy the code
The ServiceManager process is created by the init process by parsing the init.rc file.
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 drmCopy the code
Corresponding to find/frameworks/native/CMDS servicemanager/service_manager. The main method of c source files
int main(int argc, char **argv) { struct binder_state *bs; Binder_open (128*1024); binder_open(128*1024); . // Become the context manager if (binder_become_context_manager(bs)) {return -1; } // Whether the selinux permission is enabled selinux_Enabled = is_selinux_Enabled (); sehandle = selinux_android_service_context_handle(); selinux_status_open(true); If (selinux_enabled > 0) {if (seHandle == NULL) {// Abort (); } if (getcon(&service_manager_context) ! // The service_manager context abort(); }}... Binder_loop (bs, svcmgr_handler); binder_loop(bs, svcmgr_handler); return 0; }Copy the code
These are the three startup phases of the ServiceManager process:
- Open binder driver: binder_open;
- Register as a binder service master: binder_become_context_manager;
- Enter an infinite loop to process requests from the client: binder_loop;
1. Start the Binder driver
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; // 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; } / / driver version, and to determine whether a version is consistent 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); goto fail_open; } // the size of the memory size of bs->mapsize; // binder_mmap 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; Fail_map: close(bs->fd); fail_open: free(bs); return NULL; } struct binder_state {// dev/binder file descriptor int fd; // Memory address to mmap void *mapped; // Allocate memory size, default is 128KB size_t mapsize; };Copy the code
2. Register as a butler of Binder services:
int binder_become_context_manager(struct binder_state *bs)
{
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
Copy the code
Ioctl actually calls the binder_ioctl method of the driver layer. The implementation of the binder_ioctl method will be analyzed in a later article.
3. Enter the infinite loop to process the request from the client
void binder_loop(struct binder_state *bs, binder_handler func)
{
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
// 将 BC_ENTER_LOOPER 写入驱动,告诉驱动当前进程进入循环
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;
// 不断的循环等待读取 binder 驱动的数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
break;
}
// 解析远程进程的 binder 驱动信息
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;
}
}
}
int binder_write(struct binder_state *bs, void *data, size_t len)
{
struct binder_write_read bwr;
int res;
// 代表写入数据大小,大小是 len
bwr.write_size = len;
bwr.write_consumed = 0;
// 写入命令 BC_ENTER_LOOPER
bwr.write_buffer = (uintptr_t) data;
// read_size = 0,表示不读取数据
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
// 把 binder_write_read 写入 binder 驱动
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
fprintf(stderr,"binder_write: ioctl failed (%s)\n",
strerror(errno));
}
return res;
}
// ptr 是读取数据的地址,是 bwr.read_buffer
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;
while (ptr < end) {
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;
...
binder_dump_txn(txn);
if (func) {
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;
// 创建回复的 reply
bio_init(&reply, rdata, sizeof(rdata), 4);
// 从 txn 解析出 binder_io 信息
bio_init_from_txn(&msg, txn);
// 调用解析回调函数 svcmgr_handler
res = func(bs, txn, &msg, &reply);
// 像 binder 驱动发送一个回复
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;
...
binder_dump_txn(txn);
if (bio) {
bio_init_from_txn(bio, txn);
bio = 0;
}
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);
// binder 死亡消息
death->func(bs, death->ptr);
break;
}
case BR_FAILED_REPLY:
r = -1;
break;
case BR_DEAD_REPLY:
r = -1;
break;
default:
return -1;
}
}
return r;
}
void bio_init(struct binder_io *bio, void *data, size_t maxdata, size_t maxoffs) {
size_t n = maxoffs * sizeof(size_t);
if (n > maxdata) {
...
}
bio->data = bio->data0 = (char *) data + n;
bio->offs = bio->offs0 = data;
bio->data_avail = maxdata - n;
bio->offs_avail = maxoffs;
bio->flags = 0;
}
void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn)
{
bio->data = bio->data0 = (char *)(intptr_t)txn->data.ptr.buffer;
bio->offs = bio->offs0 = (binder_size_t *)(intptr_t)txn->data.ptr.offsets;
bio->data_avail = txn->data_size;
bio->offs_avail = txn->offsets_size / sizeof(size_t);
bio->flags = BIO_F_SHARED;
}
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;
//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;
// PING_TRANSACTION,能不能找到我
if (txn->code == PING_TRANSACTION)
return 0;
// 判断 code 是什么命令
switch(txn->code) {
// 查询获取 Service 服务命令
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
// 要查询的服务名称
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
// 从服务列表中寻找 handle 值
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
if (!handle)
break;
// 把 handle 值写入回复数据
bio_put_ref(reply, handle);
return 0;
// 添加服务到列表
case SVC_MGR_ADD_SERVICE:
// 获取服务的名称
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
// 获取服务的 handle 的值
handle = bio_get_ref(msg);
// 执行添加服务到列表的逻辑
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
// 从服务列表中查找服务的 handle 值
uint32_t do_find_service(struct binder_state *bs, const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
// 根据名称查找服务信息
struct svcinfo *si = find_svc(s, len);
// 找不到该服务
if (!si || !si->handle) {
return 0;
}
...
// 返回服务的 handle 值
return si->handle;
}
struct svcinfo *find_svc(const uint16_t *s16, size_t len)
{
struct svcinfo *si;
for (si = svclist; si; si = si->next) {
//当名字完全一致,则返回查询到的结果
if ((len == si->len) &&
!memcmp(s16, si->name, len * sizeof(uint16_t))) {
return si;
}
}
return NULL;
}
int do_add_service(struct binder_state *bs,
const uint16_t *s, size_t len,
uint32_t handle, uid_t uid, int allow_isolated,
pid_t spid)
{
struct svcinfo *si;
if (!handle || (len == 0) || (len > 127))
return -1;
//权限检查
if (!svc_can_register(s, len, spid)) {
return -1;
}
//服务检索
si = find_svc(s, len);
if (si) {
if (si->handle) {
// 服务已注册时,释放之前添加的相应服务
svcinfo_death(bs, si);
}
si->handle = handle;
} else {
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
// 内存不足,无法分配足够内存
if (!si) {
return -1;
}
// 指定 handle 值
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;
// svclist保存所有已注册的服务
si->next = svclist;
svclist = si;
}
// 以 BC_ACQUIRE 命令,handle 为目标的信息,通过 ioctl 发送给 binder 驱动
binder_acquire(bs, handle);
// 以 BC_REQUEST_DEATH_NOTIFICATION 命令的信息,通过 ioctl 发送给 binder 驱动,主要用于清理内存等收尾工作
binder_link_to_death(bs, handle, &si->death);
return 0;
}
void binder_send_reply(struct binder_state *bs, struct binder_io *reply, binder_uintptr_t buffer_to_free, int status) {
struct {
uint32_t cmd_free;
binder_uintptr_t buffer;
uint32_t cmd_reply;
struct binder_transaction_data txn;
} __attribute__((packed)) data;
data.cmd_free = BC_FREE_BUFFER;
data.buffer = buffer_to_free;
// reply命令
data.cmd_reply = BC_REPLY;
data.txn.target.ptr = 0;
data.txn.cookie = 0;
data.txn.code = 0;
if (status) {
data.txn.flags = TF_STATUS_CODE;
data.txn.data_size = sizeof(int);
data.txn.offsets_size = 0;
data.txn.data.ptr.buffer = (uintptr_t)&status;
data.txn.data.ptr.offsets = 0;
} else {
data.txn.flags = 0;
data.txn.data_size = reply->data - reply->data0;
data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
}
// 向 Binder 驱动通信
binder_write(bs, &data, sizeof(data));
}
Copy the code
Finally, review the addService method in the Media service addition process, which is eventually driven by binder to execute ServiceMananger’s do_add_service method across processes.
Video address: pan.baidu.com/s/1j_wgzITc…
Video password: JJ4B