ver ventajas funciones cuál como caracteristicas linux linux-kernel linux-device-driver embedded-linux

linux - ventajas - kernel windows nt



Controlador de espacio de usuario vs espacio de kernel (2)

Estoy buscando para escribir un controlador PWM. Sé que hay dos formas de controlar un controlador de hardware:

  1. Controlador de espacio de usuario.
  2. Controlador de espacio kernel

Si en general (no consideramos un caso de controlador PWM) tenemos que tomar una decisión sobre si ir para el espacio de usuario o el controlador de espacio de núcleo. Entonces, ¿qué factores tenemos que tener en cuenta aparte de estos?

  1. El controlador de espacio de usuario puede directamente la memoria mmap () / dev / mem a su espacio de direcciones virtuales y no necesita cambio de contexto.
  2. El controlador del espacio de usuario no puede tener implementados controladores de interrupción (tienen que sondear la interrupción).
  3. El controlador del espacio de usuario no puede realizar DMA (ya que la memoria compatible con DMA puede asignarse desde el espacio del kernel).

Otra consideración: es mucho más fácil depurar los controladores de espacio de usuario. Puede usar gdb, valgrind, etc. Caramba, ni siquiera tiene que escribir su controlador en C.

Hay una tercera opción más allá del simple espacio de usuario o controladores de espacio del kernel: algunos de ambos. Puede hacer solo las cosas del espacio del kernel en un controlador del kernel y hacer todo lo demás en el espacio del usuario. Es posible que ni siquiera tenga que escribir el controlador de espacio del kernel si utiliza el marco del controlador UIO de Linux (consulte https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html ).

He tenido suerte al escribir un controlador compatible con DMA casi por completo en el espacio de usuario. UIO proporciona la infraestructura para que solo pueda leer / seleccionar / epoll en un archivo para esperar una interrupción.

Debe tener en cuenta las implicaciones de seguridad de la programación de los descriptores DMA desde el espacio del usuario: a menos que tenga alguna protección en el propio dispositivo o en una IOMMU, el controlador del espacio del usuario puede hacer que el dispositivo lea o escriba en cualquier dirección de la memoria física.


De esos tres factores que mencionaste solo el primero es realmente correcto. En cuanto al resto, en realidad no. Es posible que un código de espacio de usuario realice operaciones DMA, no hay problema con eso. Hay muchas compañías de dispositivos de hardware que emplean esta técnica en sus productos. También es posible tener una aplicación de espacio de usuario controlada por interrupciones, incluso cuando toda la E / S se realiza con un bypass completo del kernel. Por supuesto, no es tan fácil simplemente hacer un mmap() en /dev/mem .

Debería tener una parte mínima de su controlador en el kernel, que se necesita para proporcionarle al usuario el espacio que necesita del kernel (porque si lo piensa, /dev/mem también está respaldado arriba por un controlador de dispositivo de carácter).

Para DMA, en realidad es demasiado fácil: todo lo que tiene que hacer es manejar la solicitud de mmap y asignar un búfer DMA al espacio del usuario. Para las interrupciones: es un poco más complicado, la interrupción debe ser manejada por el kernel sin importar qué, sin embargo, el kernel puede no hacer ningún trabajo y simplemente reactivar el proceso que llama, por ejemplo, epoll_wait() . Otro enfoque es enviar una señal al proceso como lo hizo DOSEMU, pero eso es muy lento y no se recomienda.

En cuanto a su pregunta real, un factor que debe tener en cuenta es el intercambio de recursos. Mientras no tenga que compartir un dispositivo en múltiples aplicaciones y no haya nada que no pueda hacer en el espacio de usuario, vaya al espacio de usuario. Es probable que ahorre toneladas de tiempo durante el ciclo de desarrollo, ya que escribir el código de espacio del usuario es extremadamente fácil. Sin embargo, cuando dos o más aplicaciones necesitan compartir el dispositivo (o sus recursos), lo más probable es que dedique una gran cantidad de tiempo a hacer que sea posible, solo imagine múltiples procesos de forking, fallas, mapeo (¿la misma?) Memoria al mismo tiempo, etc. Y, después de todo, IPC generalmente se realiza a través del kernel, por lo que si la aplicación tuviera que empezar a "hablar" entre sí, el rendimiento podría degradarse considerablemente. Sin embargo, esto todavía se hace en la vida real para ciertas aplicaciones críticas para el rendimiento, pero no quiero entrar en esos detalles.

Otro factor es la infraestructura del kernel. Digamos que desea escribir un controlador de dispositivo de red. Eso no es un problema para hacerlo en el espacio de usuario. Sin embargo, si lo haces, también deberías escribir una pila de red completa, ya que no será posible utilizar la predeterminada de Linux que se encuentra en el kernel.

Yo diría que vaya a buscar espacio para el usuario si es posible y la cantidad de esfuerzo para hacer que las cosas funcionen es menor que escribir un controlador del kernel, y teniendo en cuenta que algún día podría ser necesario mover el código al kernel. De hecho, esta es una práctica común para compilar el mismo código tanto para el espacio del usuario como para el espacio del kernel, dependiendo de si se define alguna macro o no, porque la prueba en el espacio del usuario es mucho más agradable.