1. 学习文章:
Android Bander设计与实现 - 设计篇:
https://blog.csdn.net/universus/article/details/6211589
红茶一杯话Binder:
https://my.oschina.net/youranhongcha/blog/149575
Android进程间通信(IPC)机制Binder简要介绍和学习计划
https://blog.csdn.net/luoshengyang/article/details/6618363/
2. ServiceManager server端实现
int main(int argc, char** argv)
{
struct binder_state *bs;
char *driver = "/dev/binder";
bs = binder_open(driver, 128*1024);
binder_become_context_manager(bs); /*ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0)*/
binder_loop(bs, svcmgr_handler);
return 0;
}
struct binder_state
{
int fd;
void *mapped;
size_t mapsize;
};
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
struct binder_state *bs;
bs = malloc(sizeof(*bs));
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
return bs;
}
{
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];
/*通过binder_write: 写入数据:BC_ENTER_LOOPER
*binder_write: 把数据转化为binder_write_read的格式和协议*/
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(uint32_t));
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
/*循环读数据:并解析读到的结果*/
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
}
}
struct binder_write_read {
binder_size_t write_size; /* bytes to write */
binder_size_t write_consumed; /* bytes consumed by driver */
binder_uintptr_t write_buffer;
binder_size_t read_size; /* bytes to read */
binder_size_t read_consumed; /* bytes consumed by driver */
binder_uintptr_t read_buffer;
};
向binder文件写数据:cmd:BINDER_WRITE_READ + binder_write_read数据类型,
binder_write_read数据结构的内容标示:是否为读写等;
write/read_size是否为0, 要写入/读到的数据在write/read_buffer里
int binder_write(struct binder_state *bs, void *data, size_t len)
{
struct binder_write_read bwr;
bwr.write_size = len;
bwr.write_consumed = 0;
bwr.write_buffer = (uintptr_t) data;
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
return res;
}
/*通过ioctl: cmd + args的形式读写\控制等*/
cmd:
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
/*如果是读写则cmd: BINDER_WRITE_READ,后面的数据格式就是: struct binder_write_read*/
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
如果来着driver的cmd是BR_TRANSACTION则后面跟随的数据格式是binder_transaction_data
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) {
/*从binder driver文件对到数据格式:cmd+ 和cmd对应的数据格式:*/
uint32_t cmd = *(uint32_t *) ptr;
ptr += sizeof(uint32_t);
switch(cmd) {
case BR_TRANSACTION: {
struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
if (func) {
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;
bio_init(&reply, rdata, sizeof(rdata), 4);
bio_init_from_txn(&msg, txn);
res = func(bs, txn, &msg, &reply);
if (txn->flags & TF_ONE_WAY) {
binder_free_buffer(bs, txn->data.ptr.buffer);
} else {
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}
}
ptr += sizeof(*txn);
break;
}
}
return r;
}
/*从binder driver file读到的cmd:*/
enum binder_driver_return_protocol {
BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
BR_REPLY = _IOR('r', 3, struct binder_transaction_data)
}
/*写入binder driver file的cmd:*/
enum binder_driver_command_protocol {
BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
BC_REPLY = _IOW('c', 1, struct binder_transaction_data)
}
cmd后面的数据格式和cmd相关, 以常见的BR_TRANSACTION为例:
struct binder_transaction_data {
/* The first two are only used for bcTRANSACTION and brTRANSACTION,
* identifying the target and contents of the transaction.
*/
union {
/* target descriptor of command transaction */
__u32 handle;
/* target descriptor of return transaction */
binder_uintptr_t ptr;
} target;
binder_uintptr_t cookie; /* target object cookie */
__u32 code; /* transaction command */
/* General information about the transaction. */
__u32 flags;
pid_t sender_pid;
uid_t sender_euid;
binder_size_t data_size; /* number of bytes of data */
binder_size_t offsets_size; /* number of bytes of offsets */
/* If this transaction is inline, the data immediately
* follows here; otherwise, it ends with a pointer to
* the data buffer.
*/
union {
struct {
/* transaction data */
binder_uintptr_t buffer;
/* offsets from buffer to flat_binder_object structs */
binder_uintptr_t offsets;
} ptr;
__u8 buf[8];
} data;
};
/*binder_transaction_data 和binder_io 的区别,为什么有引入binder_io?*/
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
/*return transaction: 检查brTransaction的Target是否为BINDER_SERVICE_MANAGER*/
if (txn->target.ptr != BINDER_SERVICE_MANAGER)
return -1;
/*从传入的数据获得:strict_policy*/
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
switch(txn->code) {
case SVC_MGR_ADD_SERVICE:
/*从传入的数据获得:service name*/
s = bio_get_string16(msg, &len);
/*flat_binder_object: representation of a Binder object for transfer between process
*哪里形成了flat_binder_object
*/
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
}
bio_put_uint32(reply, 0);
return 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;
}
struct binder_io
{
char *data; /* pointer to read/write from */
binder_size_t *offs; /* array of offsets */
size_t data_avail; /* bytes available in data buffer */
size_t offs_avail; /* entries available in offsets array */
char *data0; /* start of data buffer */
binder_size_t *offs0; /* start of offsets buffer */
uint32_t flags;
uint32_t unused;
};
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;
{
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
si->handle = handle;
si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '\0';
si->allow_isolated = allow_isolated;
si->next = svclist;
svclist = si;
}
binder_acquire(bs, handle);
return 0;
}
void binder_acquire(struct binder_state *bs, uint32_t target)
{
uint32_t cmd[2];
cmd[0] = BC_ACQUIRE;
cmd[1] = target;
binder_write(bs, cmd, sizeof(cmd));
}
server注册是通过是ServiceManager代理把server注册,这里有点绕。
{
struct binder_state *bs;
char *driver = "/dev/binder";
bs = binder_open(driver, 128*1024);
binder_become_context_manager(bs); /*ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0)*/
binder_loop(bs, svcmgr_handler);
return 0;
}
2.1. binder_open
/*初始化 binder_state: */struct binder_state
{
int fd;
void *mapped;
size_t mapsize;
};
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
struct binder_state *bs;
bs = malloc(sizeof(*bs));
bs->fd = open(driver, O_RDWR | O_CLOEXEC);
bs->mapsize = mapsize;
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
return bs;
}
2.2. binder loop
void binder_loop(struct binder_state *bs, binder_handler func){
int res;
struct binder_write_read bwr;
uint32_t readbuf[32];
/*通过binder_write: 写入数据:BC_ENTER_LOOPER
*binder_write: 把数据转化为binder_write_read的格式和协议*/
readbuf[0] = BC_ENTER_LOOPER;
binder_write(bs, readbuf, sizeof(uint32_t));
bwr.write_size = 0;
bwr.write_consumed = 0;
bwr.write_buffer = 0;
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
/*循环读数据:并解析读到的结果*/
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
}
}
2.2.1 向binder驱动文件写数据:binder write
/*向binder写/读数据都是通过结构体:binder_write_read:用读写大小区分读写:如果是写则把读大小设为0*/struct binder_write_read {
binder_size_t write_size; /* bytes to write */
binder_size_t write_consumed; /* bytes consumed by driver */
binder_uintptr_t write_buffer;
binder_size_t read_size; /* bytes to read */
binder_size_t read_consumed; /* bytes consumed by driver */
binder_uintptr_t read_buffer;
};
向binder文件写数据:cmd:BINDER_WRITE_READ + binder_write_read数据类型,
binder_write_read数据结构的内容标示:是否为读写等;
write/read_size是否为0, 要写入/读到的数据在write/read_buffer里
int binder_write(struct binder_state *bs, void *data, size_t len)
{
struct binder_write_read bwr;
bwr.write_size = len;
bwr.write_consumed = 0;
bwr.write_buffer = (uintptr_t) data;
bwr.read_size = 0;
bwr.read_consumed = 0;
bwr.read_buffer = 0;
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
return res;
}
/*通过ioctl: cmd + args的形式读写\控制等*/
cmd:
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
/*如果是读写则cmd: BINDER_WRITE_READ,后面的数据格式就是: struct binder_write_read*/
ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
2.2.2 从binder driver文件中读取数据
读到的内容格式是cmd + data(数据格式和cmd向对应):这里的cmd和操作binder driver文件的cmd不是一个层次.如果来着driver的cmd是BR_TRANSACTION则后面跟随的数据格式是binder_transaction_data
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) {
/*从binder driver文件对到数据格式:cmd+ 和cmd对应的数据格式:*/
uint32_t cmd = *(uint32_t *) ptr;
ptr += sizeof(uint32_t);
switch(cmd) {
case BR_TRANSACTION: {
struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
if (func) {
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;
bio_init(&reply, rdata, sizeof(rdata), 4);
bio_init_from_txn(&msg, txn);
res = func(bs, txn, &msg, &reply);
if (txn->flags & TF_ONE_WAY) {
binder_free_buffer(bs, txn->data.ptr.buffer);
} else {
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}
}
ptr += sizeof(*txn);
break;
}
}
return r;
}
/*从binder driver file读到的cmd:*/
enum binder_driver_return_protocol {
BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
BR_REPLY = _IOR('r', 3, struct binder_transaction_data)
}
/*写入binder driver file的cmd:*/
enum binder_driver_command_protocol {
BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
BC_REPLY = _IOW('c', 1, struct binder_transaction_data)
}
cmd后面的数据格式和cmd相关, 以常见的BR_TRANSACTION为例:
struct binder_transaction_data {
/* The first two are only used for bcTRANSACTION and brTRANSACTION,
* identifying the target and contents of the transaction.
*/
union {
/* target descriptor of command transaction */
__u32 handle;
/* target descriptor of return transaction */
binder_uintptr_t ptr;
} target;
binder_uintptr_t cookie; /* target object cookie */
__u32 code; /* transaction command */
/* General information about the transaction. */
__u32 flags;
pid_t sender_pid;
uid_t sender_euid;
binder_size_t data_size; /* number of bytes of data */
binder_size_t offsets_size; /* number of bytes of offsets */
/* If this transaction is inline, the data immediately
* follows here; otherwise, it ends with a pointer to
* the data buffer.
*/
union {
struct {
/* transaction data */
binder_uintptr_t buffer;
/* offsets from buffer to flat_binder_object structs */
binder_uintptr_t offsets;
} ptr;
__u8 buf[8];
} data;
};
/*binder_transaction_data 和binder_io 的区别,为什么有引入binder_io?*/
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
/*return transaction: 检查brTransaction的Target是否为BINDER_SERVICE_MANAGER*/
if (txn->target.ptr != BINDER_SERVICE_MANAGER)
return -1;
/*从传入的数据获得:strict_policy*/
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
switch(txn->code) {
case SVC_MGR_ADD_SERVICE:
/*从传入的数据获得:service name*/
s = bio_get_string16(msg, &len);
/*flat_binder_object: representation of a Binder object for transfer between process
*哪里形成了flat_binder_object
*/
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
}
bio_put_uint32(reply, 0);
return 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;
}
struct binder_io
{
char *data; /* pointer to read/write from */
binder_size_t *offs; /* array of offsets */
size_t data_avail; /* bytes available in data buffer */
size_t offs_avail; /* entries available in offsets array */
char *data0; /* start of data buffer */
binder_size_t *offs0; /* start of offsets buffer */
uint32_t flags;
uint32_t unused;
};
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;
{
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
si->handle = handle;
si->len = len;
memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
si->name[len] = '\0';
si->allow_isolated = allow_isolated;
si->next = svclist;
svclist = si;
}
binder_acquire(bs, handle);
return 0;
}
void binder_acquire(struct binder_state *bs, uint32_t target)
{
uint32_t cmd[2];
cmd[0] = BC_ACQUIRE;
cmd[1] = target;
binder_write(bs, cmd, sizeof(cmd));
}
server注册是通过是ServiceManager代理把server注册,这里有点绕。