Binder from Unfamiliar to Familiar (Middle)

Binder from Unfamiliar to Familiar (ii)

concept

What is the Binder

If a colleague asked me, “Binder is what?” some of my answers might come to mind

  • Interprocess Communication mechanism (IPC) in Android
  • Is also an Android system in the Linux kernel layer driver device
  • In Android development, if inheritedBinder.javaClasses that implementIBinderInterface, which enables cross-process communication

Multiple processes in Android

So when will multiple processes be used in Android? In our usual Android development, we will create some independent processes, such as: WebView, large picture browsing, audio and video playback, push and other related functions, while the Android system services in the phone, alarm clock and other functions are also multi-process implementation. If you write android applications to achieve the process, so your application can open up more memory, each process can apply to the virtual machine to use memory is limited, so multiple processes can get more memory), can obtain risk isolation (put some risk operation unified in one process, even if the process is collapsed, Does not affect the main process), these are the advantages of multi-process.

Interprocess communication in Linux

Existing interprocess communication means in Linux include

  • Pipe (named Pipe): 1 page of memory is allocated at creation time. The cache size is limited
  • Signal and Trace: not suitable for information exchange, more suitable for process interrupt control, such as illegal memory access, killing a process, etc
  • Shared Memory: No information copy, the shared buffer directly attached to the process virtual address space, fast; However, the synchronization problem between processes cannot be realized by the operating system and must be solved by each process using the synchronization tool
  • The Socket (Socket): As a more general interface, the transmission efficiency is low. It is mainly used for low-speed communication between different processes on the local machine or inter-process communication across the network
  • Message queue (Message queue): Information copied twice, extra CPU consumption; Not suitable for frequent or informative communication
  • Semaphores (Semaphore): usually used as a lock mechanism to prevent other processes from accessing a shared resource when one process is accessing the same resource. Therefore, it is mainly used as a means of synchronization between processes and between different threads within the same process

Since Android is based on the Linux kernel, why did Google use Binder instead of IPC? Binder and other IPC solutions are compared from the following perspectives

  1. From the perspective of performance: As a universal interface, Socket has low transmission efficiency and high cost. It is mainly used for low-speed communication between different processes on the local machine or inter-process communication across the network. The message queue and pipeline adopt store-and-forward mode, that is, the data is first from the sender’s cache to the cache created by the kernel, and then copied from the kernel cache to the receiver’s cache, at least twice. Binder requires only one copy; No copy is required for shared memory. Binders are second only to shared memory in performance

  2. From the perspective of stability: Binder is based on C/S architecture (the architecture consists of Client and Server, and the Client’s requirements are directly sent to the Server), with clear architecture, relatively independent Client and Server, and good stability. Sockets also support C/S architecture. Pipeline/message queue/shared memory/semaphore are not supported. Although a set of protocols can be set up on these underlying mechanisms to achieve client-server communication, this increases the complexity of the system, and it is difficult to guarantee the reliability in the environment with complex conditions and scarce resources such as mobile phones

  3. From the perspective of security: the receiver of traditional Linux IPC cannot obtain the reliable UID/PID of the process of the other party, so it cannot identify the other party. Android, as an open source system, has many development platforms and a wide range of APPS, so the security of mobile phones is crucial. The traditional Linux IPC has no protection measures and is completely guaranteed by the upper layer protocol. Only UID/PID can be filled in packets by users, and reliable identity identification can only be added in the kernel by the IPC mechanism itself. Moreover, the access point of traditional IPC is open, and private channels cannot be established. Android assigns its own UID to each installed application, so the PROCESS UID is an important identification of the process identity. In THE C/S architecture, only the client is exposed in the Android system. The client sends tasks to the server, and the server determines whether the UID/PID meets the access permission according to the permission control policy. At present, permission control is usually performed by popping up the permission application dialog box, allowing users to choose whether to allow permission. Binder supports both real-name binders (such as system services) and anonymous binders (self-created services) for greater security

    Binder The Shared memory Socket
    performance I need to copy it once Don’t need to copy I need to copy it twice
    The stability of Based on C/S architecture, easy to use and good stability Complex control, poor ease of use, poor stability Based on C/S architecture, as a universal interface, low transmission efficiency, high overhead, good stability
    security Assign UID to each APP, support both real name and anonymity, high security Dependent on upper-layer protocols, access points are open and insecure Dependent on upper-layer protocols, access points are open and insecure

    For these reasons, Binder is the choice for upper-layer interprocess communication on Android

    structure

How do processes communicate with each other

Two processes A and B, process A can not operate on each other or call the code in process B, because the Android system between different processes isMemory isolation. Memory is divided by the operating system into two parts, user space and kernel space. Userspace is where the user program code runs, and kernel space is where the kernel code runs. For security, they are isolated from each other, so that if a user’s program crashes, the kernel will not be affected.The CPU has different operation modes, representing different levels. Different levels have different functions. Some operations are prohibited at lower levels. Linux systems are designed to take advantage of this hardware feature, using two levels, the highest level and the lowest level, with the kernel running at the highest level (Kernel mode R0), at which all operations can take place, while applications run at lower levels (User mode R3At this level, the processor controls both direct access to the hardware and unauthorized access to memory.

When a task (process) executing a system call is trapped in kernel code, the process is said to be in kernel running state (kernel-state). The processor executes in kernel code with the highest privilege (level 0). When a process is in kernel state, the kernel code executed uses the kernel stack of the current process. Each process has its own kernel stack.

When a process is executing the user’s own code, it is said to be in user mode. At this point the processor runs in the lowest privilege level (level 3) of user code.

Kernel-mode and user-mode have their own memory mapping, that is, their own address space. The virtual memory requested by user space of different processes is mapped to the physical memory of the independent process and is isolated. The virtual memory requested by the kernel space is mapped to the same physical memory and is shared. If a user-space application wants to request system services, such as operating a physical device or mapping a device-space address to user-space, it must do so through system calls (interface functions provided by the operating system to user-space), which are mainly implemented through the following two functions

Copy_from_user () // copies data from user space to kernel space copy_to_user() // copies data from kernel space to user spaceCopy the code

Traditional IPC mechanisms transmit data

In the traditional IPC mechanism, data transfer is equivalent to A pager. If process A wants to send A message to process B, the message needs to be sent to the paging center, which then sends the message to process B’s pager. This message is sent twice, which is called double copy.

Binder mechanisms transfer data

With A Binder mechanism, process A sends A package to process B. Process A delivers the package to the Courier company. The Courier company then puts the package in its own container, and Process B picks it up directly from the container. This package is equivalent to the data, but A copy occurs when process A is delivered to the Courier company (just for example, easy to understand). In this process, the space of the express container is shared by the express company and process B.

To understand how Binder mechanisms transfer data, you must first understand a concept: memory mapping

Linux initializes the contents of a virtual memory area by associating it with objects on a disk (physical memory), a process called Memory mapping

MMAP works like this:

1. The thread starts the mapping process and creates a virtual mapping area for the mapping in the virtual address space.

Firstly, the library function Mmap is called in user space, and an idle segment of continuous virtual address satisfying the requirements is found in the virtual address space of the current process as the virtual memory mapping area, which is initialized and inserted into the virtual address area list or tree of the process.

2. The system invokes the kernel function Mmap in the kernel space to implement the one-to-one mapping between the physical address of a file and the virtual address of a process.

3. The process initiates the access to the mapping space

A process read/write accesses the virtual address, queries the page table, and finds that the address is not on a physical page in memory because the file has not been moved from disk to memory, although the mapping has been established. A page miss interrupt occurs, and the kernel requests a page call from disk. The paging process is first searched in swap cache. If not, the missing page is called from disk into memory through the noPage function. The process then reads and writes the dirty page. If the write operation changes the page content, the system automatically writes back the dirty page to the disk after a period of time. (Dirty modified pages are not immediately updated to the file, you can call msync() to force the synchronization and write to the file)

The memory mapping involved in the Binder IPC mechanism is implemented through Mmap (), a method of memory mapping in operating systems. After the mapping relationship is established, the modification of the user space can be directly reflected in the kernel space. Conversely, changes made to this area in kernel space can be directly reflected in user space. In this way, data copied from the sender user space to the kernel-space cache is copied directly to the receiver user space cache, reducing the need for a single copy of data.

Binder frame construction

1. The Binder

Linux abstracts all hardware access to read, write, and set files, and the concrete implementation of this “abstraction” is the driver. The driver acts as a hub between hardware and software, providing a standardized set of calls and mapping those calls to actual hardware device-specific operations, hiding the details of how the device works from the application.

Linux driver devices fall into three categories: character devices, block devices, and network devices. A character device is a device that can be accessed like a byte stream file. When a character device is read/written, I/O of the actual hardware generally follows. Character device drivers typically implement open, close, read, and write system calls, such as display, keyboard, serial port, LCD, LED, and so on.

Block devices refer to devices that transfer 512 KB or 1 KB of data, such as hard disks, SD cards, USB flash drives, and cd-RoMs.

Network devices are devices that can exchange data with other hosts, such as network cards and Bluetooth devices.

The character device has a special MISC miscellaneous device, device number 10, that automatically generates device nodes. Ashmem and Binder for Android are misC miscellaneous devices.

Binder is not part of the Linux Kernel, thanks to Linux’s Loadable Kernel Module (LKM) mechanism. A module is a self-contained program that can be compiled separately but cannot be run independently. It is linked to the kernel at run time and runs as part of the kernel. In this way, the Android system can dynamically add a kernel module that runs in the kernel space and acts as a bridge for communication between user processes

For Binder mechanism, Binder driver is the router of IPC communication, responsible for data interaction between different processes, which is the core of Binder mechanism. For Linux systems, a Binder driver is a character driver device that runs in kernel space and provides upper layer /dev/binder device nodes and system calls such as open, Mmap, and IOCtl

2.ServiceManager

The Service Manager acts as a binder-driven daemon, similar to DNS in TCP communications. We will register relevant binders into it, and finally find the proxy side of Binder through the Service Manager Service. In fact, the Service Manager was the first Service registered with Android Binder

3.Clinet

Local end, Binder the end of the whole IPC process communication that makes requests. Equivalent to the concept of client in C/S architecture

4.Server agent, Binder responds to requests during the communication of the whole IPC process. Equivalent to the concept of server side in C/S architecture