Basic data structure collation in Android binder driver

Source: Internet
Author: User

Recently saw a blog, is to talk about the binder principle, before looking at the deep understanding of Android I have seen, at that time do not understand. Feel this also a bit of meaning, looked for a few days, found the more see the more do not understand, and then look at Lao Luo's blog, found also not too understand, now want to according to the book of Things Good comb under binder.

The sense inside should be focused on should be Bind_node is the representative of the registered service in the kernel, BIND_REF is the client connection on the driver's behalf. Bind_buffer kernel buffer, after mmap can be in the user space operation, and then can be accessed in the kernel, Bind_proc is the representative of the process, the client and the service side have, on the top of the management, not finished, to be continued, and so finish the art exploration come over to update.

interprocess communication sets this value based on the state of the client and server

struct Binder_work {struct List_head entry;   enum {binder_work_transaction = 1,binder_work_transaction_complete,binder_work_node,binder_work_dead_binder,      //binder Driver detects a service component death, locates refs in the Binder entity object, finds the client process referencing it, and the client process actively registers a death notification to discover that the service component has died two cases                Binder_work_dead_binder_and_clear, when the//client process logs off death notification, the corresponding service component is dead, BINDER driver finds the previously registered Binder_ref_death structure, and modify it workbinder_work_clear_death_notification, the  //client process unregisters a death notice, the corresponding service component is not dead, the binder driver will find the previously registered, A binder_ref_death struct, and modifies its work to do so, and then encapsulates the struct as a working item added to the TODO queue of the client process                   } type; Type of work item};

Binders in the Binder Entity object Service are represented in the kernel

struct binder_node {int debug_id;struct binder_work work;//reference count changes when Binder_work_node and adds it to the TODO queue of the response process Union {struct RB_ Node rb_node;struct hlist_node Dead_node;};       struct Binder_proc *proc; Point to service process struct hlist_head refs; All the client binder references Binder_ref->nodeint internal_strong_refs;int local_weak_refs;int local_strong_refs;void __  User *ptr;              Pointer to a reference count inside the service component Weakref_impl weak reference count void __user *cookie;        The address that points to the service component unsigned has_strong_ref:1;    1 End 0unsigned Pending_strong_ref:1 when requesting service components;          When the request is 1,service added for 0unsigned has_weak_ref:1;  1 End 0unsigned pending_weak_ref:1;unsigned has_async_transaction:1 when requesting service components; Each transaction is associated with a Binder entity object unsigned accept_fds:1;           Whether to receive interprocess communication data containing file descriptors to prevent the source process from opening unsigned min_priority:8 in the target process;       Thread-priority struct List_head Async_todo; Asynchronous transaction Queue}; 
Service components, which maintain reference counts in the driver's Binder_node,binder_ref

Represents the death notice of the client component in the driver,

struct Binder_ref_death {struct binder_work work;   See the first data structure of void __user *cookie;  Save the address that the client is responsible for receiving the death notification object};

The binder driver determines when a service component death notification is sent to the client process. The BINDER_REF_DEATH structure is encapsulated as a work item. Added to the TODO queue of the client process, the client process is handling this work item, which is done by binder_ref_death the struct member variable, see the enumeration value in the first struct

Describes a binder reference object the binder reference in the client process is represented in the driver

struct BINDER_REF {/* lookups needed: *//*   node + proc = ref (transaction) *//*   desc + proc = ref (TRANSAC tion, inc/dec ref) *//*   node = refs + procs (proc exit) */int debug_id;struct Rb_node Rb_node_desc;      Saves all handle values within the process struct Rb_node rb_node_node;struct hlist_node node_entry;  The nodes in the hash list correspond with binder_node->refsstruct Binder_proc *proc;     Binder references the host process of the object struct Binder_node *node;   Binder Reference object refers to Binder entity object uint32_t desc;              In the client process user space, the Binder reference object is described using a handle value, the binder driver can be found by the handle value for the Binder Reference object is binder_ref              int strong; int weak; struct Binder_ref_death *death;  The place where the client process registered death notification is saved};

Process corresponds to kernel buffer

struct Binder_buffer {struct List_head entry;/* Free and allocated entries by ADDESSS *   ///kernel buffer list one node struct Rb_node Rb_node; /* Free entry by size or allocated entry *//* by address */   //free to 1 for one node in the idle kernel buffer unsigned free:1;      1 indicates that the kernel buffer is idle and the  unsigned Allow_user_free:1;//service component that does not allocate a physical page is found to request the binder driver to release the kernel buffer        when the 1,service component is finished processing unsigned async_transaction:1;   1 represents the asynchronous transaction unsigned debug_id:29;struct binder_transaction *transaction;  Each transaction is associated with a target Binder entity object struct Binder_node *target_node;size_t data_size;     The size of the data buffer size_t offsets_size; The offset array  records the position of each binder object in the re-data buffer uint8_t data[0];    Point to a variable-sized data buffer, which holds the data in the store to hold the data, and the binder binder   driver only cares about binder objects};

The process calls Open/dev/binder and creates the delegate that saves it in the global hash process in the driver

struct Binder_proc {struct Hlist_node proc_node;       is the node struct rb_root threads in the hash list;         struct RB_ROOT nodes;                        A collection of binder entity objects with PTR as the keyword struct rb_root refs_by_desc;struct rb_root refs_by_node;int pid; The struct of the process group Vm_area_struct *VMA;    Kernel buffer address user space address use struct task_struct *tsk inside the application;    Task control block struct Files_struct *files;       File structure array struct Hlist_node deferred_work_node;              Process delay execution of work item int deferred_work; Delay the specific contents of the work item void *buffer;  Kernel buffer address kernel space address chunk space is divided into binder_buffer small space ptrdiff_t user_buffer_offset;    The difference between the user-space address and the kernel-space address in the kernel buffer list_head buffers;    Point to the head of the list struct rb_root free_buffers; Assigned physical page struct rb_root allocated_buffers;size_t free_async_space;   Saves the size of the asynchronous transaction data buffer struct page **pages;    For each element in the physical page array point to a physical page size_t buffer_size;    Mmap after the kernel buffer size uint32_t buffer_free;   Size of the free kernel buffer struct list_head todo;       Encapsulates the pending request into a work item, plus the queue of pending work Items wait_queue_head_t wait;      Idle Binder thread sleeps in waiting queue   struct Binder_stats stats;   Statistics process data, process see the number of requests struct list_head delivered_death;  The death notice is encapsulated as a work item saved in a queue described, and the process receives an int max_threads;int requested_threads when it is received;   Drive the active request process to register a thread when added 1, process response minus 1int requested_threads_started;//driver actively request the number of process registrations, process response plus 1int ready_threads;    The current number of free binder threads long default_priority; The host process's priority struct dentry *debugfs_entry;};
Possible values for Deferred_work

Enum Binder_deferred_state {binder_deferred_put_files    = 0x01,//process Close file descriptor Binder_deferred_flush        = 0x02,// The wake-up thread checks whether the process has new work items that need to process binder_deferred_release      = 0x04,//no longer uses binder interprocess communication mechanism, drives free its allocated resources, releases process structure, binder entity object};
The binder driver assigns a file descriptor to the kernel buffer, and the process can map the kernel buffer to its own address space through the file descriptor

A thread in the binder thread pool that is created by the driver when the thread registers to the binder driver

struct Binder_thread {struct Binder_proc *proc;   Point to Host process struct Rb_node rb_node;    a node int pid;    Thread Idint looper;   State struct binder_transaction *transaction_stack;  When a transaction is handed over to a thread, the transaction is encapsulated into a struct to deal with who, who placed the most front-end struct list_head todo; The client process request uint32_t Return_error; /* Write failed, return error code in read BUF * * The exception that occurs when processing a transaction uint32_t Return_error2; /* Write failed, return error code in read *//* buffer.    used when sending a reply to a dead process that *//* we is also waiting on */wait_queue_head_t wait;   Wait for the dependent thread to process the end struct binder_stats stats; The number of inter-process communication requests received};

The state of the thread

enum {binder_looper_state_registered  = 0x01,//received user thread sent bc_register_looperbinder_looper_state_entered     = 0x02,//indicates readiness bc_enter_looperbinder_looper_state_exited      = 0x04,binder_looper_state_invalid     = 0x08,binder_ Looper_state_waiting     = 0x10,//binder thread in idle state Binder_looper_state_need_return = 0x20//initialization state};
Thread is actively registered by the application, then it notifies the binder driver by Bc_enter_looper

Describe inter-process communication processes

struct Binder_transaction {int debug_id;struct binder_work work;   The binder driver sets binder_work_transaction after creating a transaction for the target thread, and adds the Binder_thread *from to the TODO queue of the target thread;  The thread that initiates the transaction becomes the source thread struct binder_transaction *from_parent;    struct Binder_proc *to_proc;  Process for handling the transaction struct Binder_thread *to_thread;    Target thread struct binder_transaction *to_parent;  The transaction is processed and then returned to the parent transaction unsigned need_reply:1; 1 means synchronous transaction/* unsigned is_dead:1; *//* not used at the moment */struct Binder_buffer *buffer;   The binder driver allocates a memory buffer for the transaction unsigned intcode;unsigned intflags;longpriority; Thread-priority longsaved_priority;   Save the original thread priority Uid_tsender_euid; Thread User ID};
Application through IO command and driver interaction
#define Binder_write_read   _iowr (' B ', 1, struct binder_write_read)

Inter-process communication

struct Binder_write_read {signed longwrite_size;/* bytes to write */buffer size signed longwrite_consumed;/* bytes consumed by D   River */Drive bytes processed from buffer unsigned longwrite_buffer; The data that describes the input data transferred from the user space to the binder driver points to a user buffer address signed long read_size;/* bytes to read */signed longread_consumed;/* bytes cons Umed by driver */unsigned Longread_buffer; Point to the address of a user-space buffer};

All processes are sent to binder driver

Enum Binderdrivercommandprotocol {       bc_transaction = _iow (' C ', 0, struct binder_transaction_ Data),       bc_reply = _iow (' C ', 1, struct binder_transaction_data),       BC_FR Ee_buffer = _iow (' C ', 3, int),//point to kernel buffer        bc_increfs = _iow (' C ', 4, int),  //binder Reference object's handle value Weak references        Bc_acquire = _iow (' C ', 5, int),  //Add strong reference count        Bc_release = _io W (' C ', 6, int),       bc_decrefs = _iow (' C ', 7, int),  //weak references       BC_INCREF S_done = _iow (' C ', 8, struct Binder_ptr_cookie),       Bc_acquire_done = _iow (' C ', 9, struct BINDER_PT R_cookie),      Bc_register_looper = _io (' C ', one-to-one),  //driver request process Register thread to drive       Bc_ent Er_looper = _io (' C ', '),    //thread active registration        Bc_exit_looper = _io (' c ', +),  //thread to exit &N Bsp      Bc_reQuest_death_notification = _iow (' c ', +, struct Binder_ptr_cookie),//register        bc_clear_death_ NOTIFICATION = _iow (' c ', +, struct Binder_ptr_cookie),//empty       Bc_dead_binder_done = _iow (' c ', +, Voi D *),  //points to a death notification structure Binder_ref_death address          // The client uses the command protocol code to notify the binder driver that the service component has finished processing the death notice};
The source process uses the command protocol code bc_transaction to request that the binder driver pass the communication data to the target process

The target process uses the command protocol code bc_reply the request driver to pass the result to the source process after processing the request operation of the source process

Return Protocol Code

Enum Binderdriverreturnprotocol {br_error = _ior (' R ', 0, int),//Driver processing request error      BR_OK = _io (' R ', 1),//Successful processing & nbsp;   br_transaction = _ior (' R ', 2, struct binder_transaction_data),//notifies the server process to handle the inter-process communication request    & nbsp br_reply = _ior (' R ', 3, struct binder_transaction_data),//server after processing the request, the driver returns the client process with this Protocol br_dead_reply = _io (' R ', 5 ),  //discovers that the target process or thread has died the driver will return this protocol code br_transaction_complete = _io (' R ', 6),//When binder driver receives bc_transaction from the process or bc_rep LY, the driver returns this code, informs the process that it has received     br_increfs = _ior (' R ', 7, struct Binder_ptr_cookie),     br_acquire = _ior (' R ', 8, struct Binder_ptr_cookie),     br_release = _ior (' R ', 9, struct Binder_ptr_cookie),  &N Bsp  br_decrefs = _ior (' R ', ten, struct binder_ptr_cookie), Br_noop = _io (' R ', 12),//notifies the application that the process has performed an empty operation Br_spaw N_looper = _io (' R ', 13),///The discovery process does not have enough free BINDER threads to handle inter-process communication requests, notifies the process to add a thread to the BINDER thread pool     Br_dead_binder = _ IOR (' R ', *, void *),//whenWhen the driver detects a service component death, notifies the client process Br_clear_death_notification_done = _ior (' R ', *, void *) and returns this code notification after the//binder driver finishes executing the logoff Clien T process     br_failed_reply = _io (' R ', 17),////processing process sends a Bc_transaction exception, returns this code};


Describes a binder entity object or a reference

struct Binder_ptr_cookie {void *ptr;  The handle of the binder reference or the address of the void *cookie;//receiving the death notification object};
Data transmitted by communication in the thread of the process
struct Binder_transaction_data {union {size_thandle;/* target descriptor of command transaction *//reference object handle value void*ptr;/* Target descriptor of return transaction *  //point to address of weak reference count inside service component} target;void*cookie;/* target object cookie */
   //the address of the target service component unsigned intcode;/* transaction command *////////////general information, about the transaction. */unsigned intflags;  Describe the characteristics of inter-process communication behavior pid_tsender_pid;  The piduid_tsender_euid of the process;   size_tdata_size;/* the size of the communication data */size_toffsets_size;/* the size of the offset array */union {struct {/* transaction data */const Void*buffer; Pointing to the data buffer, the size of the true save communication data is determined by data_size/* offsets from buffer to flat_binder_object structs */const void*offsets; Save the position of each binder object, pointing to the first address of the flattened structure} ptr;//when the data volume is large uint8_tbuf[8]; Data when the volume is small;   Data buffers are to transmit data};
The above flags are valued as follows
Enum Transaction_flags {tf_one_way= 0x01,/* 1 represents asynchronous interprocess communication process */tf_root_object= 0x04,/* contents is the component ' s ROOT obje CT */tf_status_code= 0x08,/* 1 indicates that the content of the data buffer is a 4-byte status code */tf_accept_fds= 0x10,/* 0 indicates that the source process does not allow the result protector to contain the file descriptor */};
Each binder object in the data buffer uses a flat_binder_object to describe
struct Flat_binder_object {/* 8 bytes for large_flat_header. */unsigned Longtype;   Distinguishes between a binder entity object or a reference object, or a file descriptor unsigned longflags;  Only the binder entity is described, which makes sense/* 8 bytes of data. */union {void*binder;/* Local Binder entity object points to the address of an internal weak reference object */signed longhandle;/* The handle value of the remote Binder Reference object */};/* extra data ociated with local object */void*cookie;  The address that points to the service component};
The values of type in a flat structure are as follows
#define B_PACK_CHARS (C1, C2, C3, C4) (((((c1) <<24)) | (((C2) <<16)) | (((C3) <<8)) | (C4)) #define B_type_large 0x85enum {binder_type_binder= b_pack_chars (' s ', ' B ', ' * ', b_type_large),//strong type BINDER entity object Binder_ Type_weak_binder= b_pack_chars (' W ', ' B ', ' * ', b_type_large),//weak-type Entity object binder_type_handle= b_pack_chars (' s ', ' h ', ' * ', B_type_large),//description is strongly typed Binder Reference object binder_type_weak_handle= b_pack_chars (' W ', ' h ', ' * ', b_type_large),//weak type reference Binder_ type_fd= B_pack_chars (' f ', ' d ', ' * ', b_type_large),//};

Basic data structure collation in Android binder driver

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.