Comprensión profunda de Binder

Nunca antes entendí Binder lo suficiente y solo sabía un poco sobre él, así que recientemente me tomé el tiempo para comprenderlo en profundidad y hacer un resumen aquí.

Binder es un mecanismo para implementar IPC (comunicación entre procesos) en el sistema Android. El significado original de Binder es "pegamento, adhesivo", por lo que se puede imaginar que su propósito es "pegar" dos procesos como pegamento, para que IPC se pueda implementar fácilmente.

Entonces, ¿por qué existe la comunicación de procesos? Esto se debe a que los procesos están aislados en Linux, lo que significa que el proceso A no conoce la existencia del proceso B y el proceso B correspondiente no conoce la existencia del proceso A. La memoria de los dos procesos A y B no se comparte, por lo que si los datos del proceso A se van a transferir al proceso B, se debe utilizar IPC.

Aquí hay otro punto de divulgación científica sobre el espacio de proceso: el espacio de proceso se puede dividir en espacio de usuario y espacio de kernel. En pocas palabras, el espacio del usuario es el espacio donde se ejecutan los programas del usuario y el espacio del kernel es el espacio donde se ejecuta el kernel. Debido a que los programas de usuario no pueden simplemente llamar a algo tan crucial y de bajo nivel como el kernel, el kernel necesita estar protegido, por lo que se crea el espacio del kernel y el kernel se ejecuta en el espacio del kernel, de modo que no sea el espacio del usuario. es interferido casualmente. El espacio de usuario entre los dos procesos no se comparte, pero sí el espacio del kernel.

Entonces, aquí algunos estudiantes tendrán una idea audaz. La comunicación entre dos procesos se puede lograr utilizando el espacio del kernel, porque su espacio del kernel es compartido, por lo que los datos no se transmitirán. Pero entonces surge otro problema: para garantizar la seguridad, el espacio del usuario y el espacio del kernel también están aislados. Entonces, ¿cómo transferir datos desde el espacio de usuario del remitente al espacio del kernel?

Se proporciona una llamada al sistema para resolver este problema, que permite a los programas de usuario llamar a los recursos del kernel. Las llamadas al sistema son la única forma en que el espacio del usuario accede al espacio del kernel, lo que garantiza que todo el acceso a los recursos esté bajo el control del kernel, evita el acceso no autorizado a los recursos del sistema por parte de los programas del usuario y mejora la seguridad y estabilidad del sistema (este párrafo Las palabras provienen de "Análisis de los principios de Binder escritos para ingenieros de aplicaciones de Android"). Nuestras operaciones habituales de red y E/S en realidad se ejecutan en el espacio del kernel a través de llamadas al sistema (es decir, el estado del kernel).

En este punto, tenemos un plan de implementación aproximado para IPC: los datos del proceso A se transfieren al espacio del kernel (es decir, copy_from_user) a través de llamadas al sistema, y ​​el espacio del kernel luego usa las llamadas del sistema para transferir el datos para procesar B. (es decir, copiar_a_usuario). Este es también el principio de implementación actual de la comunicación IPC tradicional en Linux. Puede ver que hay dos copias de datos.

(La imagen proviene de "Análisis de los principios de Binder para ingenieros de aplicaciones de Android")

Algunos métodos de IPC en Linux:

A través de la explicación anterior, podemos Ya sabes, IPC requiere espacio en el kernel para soportarlo. Las tuberías, sockets, etc. en Linux están todos en el kernel. Pero no hay Binder en el sistema Linux. Entonces, ¿cómo se utiliza Binder para implementar IPC en Android?

Se trata de módulos cargables del kernel dinámico en Linux. Los módulos cargables del kernel dinámico son programas con funciones independientes que se pueden compilar por separado, pero no se pueden ejecutar de forma independiente. Está vinculado al kernel en tiempo de ejecución y se ejecuta como parte del kernel.

De esta manera, el sistema Android puede ejecutarse en el espacio del kernel agregando dinámicamente un módulo del kernel, y la comunicación entre los procesos del usuario se puede lograr a través de este módulo del kernel como puente. (Este pasaje proviene de "Análisis de los principios de Binder para ingenieros de aplicaciones de Android") En Android, este módulo del kernel es el controlador de Binder.

Además, en comparación con el IPC tradicional de Linux anterior, el principio de IPC de Binder solo requiere una copia de datos para completarse. Entonces, ¿cómo se hace?

De hecho, Binder se implementa con la ayuda de mmap (mapeo de memoria). mmap se utiliza para asignar archivos u otros objetos a la memoria, generalmente en sistemas de archivos con medios físicos. En pocas palabras, mmap puede establecer una relación de mapeo entre el área de memoria en el espacio del usuario y el área de memoria en el espacio del kernel, reduciendo así la cantidad de copias de datos. Los cambios en el área de memoria de cualquiera de las partes se reflejarán en la otra parte.

Por lo tanto, lo que hace Binder es crear un dispositivo virtual (el controlador del dispositivo es /dev/binder) y luego crear un área de búfer para la recepción de datos en el espacio del kernel. Esta área de búfer se combinará con. el área del búfer de memoria y los datos recibidos El espacio de usuario del proceso establece un mapeo, de modo que el proceso de envío de datos envía los datos a la memoria caché, y los datos se asignarán indirectamente al espacio de usuario del proceso de recepción, reduciendo uno copia de datos. Puede ver la siguiente imagen para obtener más detalles

(La imagen proviene de "Análisis de los principios de Binder para ingenieros de aplicaciones de Android")

Las ventajas de Binder

En todo el proceso de comunicación de Binder se puede dividir en cuatro partes:

Entre ellas, el Cliente y el Servidor se implementan mediante la capa de aplicación, mientras que el controlador Binder y ServiceManager se implementan mediante la capa inferior del sistema Android.

El proceso específico es el siguiente:

(El diagrama esquemático del proceso de comunicación de Binder proviene del "Análisis de los principios de Binder escritos para ingenieros de aplicaciones de Android")