Leyendo Be Book – cómo hacer un driver

Introducción

Escribir el driver de un dispositivo requiere conocimientos adicionales de cómo funciona BeOS/Haiku. Este artículo es parte traducción parte cosecha propia, es traducción de los capítulos de BeBook acerca de cómo programar un driver.

El Kernel y el Driver Author

El Kernel de BeOS/Haiku contiene las funcionalidades básicas del sistema operativo:

  • El proceso de inicio del sistema
  • La gestión de memoria y los hilos
  • Administrar el bus PCI e ISA
  • Gestionar el sistema de archivos (devfs, administra /dev), el sistema raíz (rootfs, administra /)
  • Otras cosas…

Eso no es suficiente para la mayoría de las aplicaciones, el Kernel es extensible utilizando add-ons. Durante el inicio del sistema se cargan addons para manejar cosas como:

  • Sistemas  de archivos reales, como FAT, NTFS…
  • Dispositivos, como la pantalla, el ratón, el teclado…
  • Los Buses del sistema, etc…

Tipos de Kernel Add-on

Hay 3 tipos de Kernel Add-on:

  1. Los drivers de dispositivos son add-ons que se comunican directamente con el dispositivo.
  2. Los módulos del espacio del kernel que exportan API para su uso con los drivers (o por otros módulos).
  3. Los sistemas de archivos son add-ons que soportan tipos específicos, como son BFS, DOSFS,HFS…

Drivers de dispositivos

Un driver de dispositivo es un add-on que reconoce un determinado dispositivo ( o una clase de éstos) y permite entender al resto del sistema para comunicarse con él. Normalmente esta comunicación implica el uso de protocolo específico de comunicación. Por ejemplo. si el sistema quiere usar una tarjeta de red Ethernet o una tarjeta gráfica, es necesario cargar addon que hace de driver del dispositivo que conoce como comunicarse con esa tarjeta. De manera similar, el código que conoce como hablar con una determinada clase de dispositivos (discos SCSI, dispositivos ATA, USB, etc.) debe implementarse como un addon que hace las veces de driver de dispositivo.

Los apartados de módulos y sistemas de archivos no han sido traducidos.

Interactuando con el Kernel

El kernel dispone de diversos servicios que pueden usarse con los drivers y los módulos. Esto incluye:

  • Habilitar y desabilitar interrupciones.
  • Configurar la para memoria para el acceso directo a memoria (DMA).
  • Acceder a otros dispositivos y módulos.

El Kernel además, a nivel de usuario, dispone de un API cuasi-Posix para el acceso a dispositivos. Una aplicación puede abrir un dispositivo con open(), y usarlo con read(), write() e ioctl() para acceder al mismo.

Las llamadas Posix son convertidas a llamadas del sistema por el propio kernel, el cual usa vía devfs, el driver apropiado. El apartado de devfs no ha sido traducido.

Principios de implementación de Drivers

Gran parte de la estabilidad de BeOS/Haiku se debe a que existe un muro entre el kernel y las aplicaciones de usuario. Los drivers son grietas en este muro. Si un driver se comporta mal o falla, hay una gran posibilidad de que esto acuse un comportamiento inesperado o tire por completo al sistema. Es absolutamente crítico que los drivers no sólo sean cuidadosamente testados antes de ser publicados, además ellos deben seguir los siguientes principios al pie de la letra.

  • Kernel Space vs. User Space (espacio del Kernel contra espacio de usuario)

Una forma que puede reducir el riesgo de que el driver cause un fallo en el sistema es poniendo la mayoría del código en el espacio de usuario. Crear un driver que… [aquí he parado de traducir].

  • Código de sincronización
  • Funciones disponibles durante el Spinlocks
  • Usando Spinlocks
  • Deshabilitando interrupciones
  • Funciones disponibles cuando las interrupciones están deshabilitadas
  • No bloquees
  • No te adelantes
Anuncios

Haciendo un driver para Haiku OS

Introducción

Este artículo es parte traducción, parte cosecha propia, de un artículo publicado en la página oficial de Haiku. Ni que decir tiene que no pretendo con esto tener nada funcional, sino tener simplemente un artículo informativo de cuales son los primeros pason  para realizar un driver para esta plataforma. Lo que quiero con este artículo es colmar mi curiosidad.

Interfaz con el sistema operativo

El kernel driver se carga durante el inicio del sistema operativo, es iniciado por el sistema operativo y publicado en el área de usuario, pudiendo acceder al driver utilizando “user hooks”.

Para programar un kernel driver necesitamos codificar las siguientes rutinas:

  • init_hardware()
  • init_driver()
  • uninit_driver()
  • find_device()
  • publish_devices()

Los kernel drivers están dentro de dos carpetas en Haiku:

  • /boot/beos/system/add-ons/kernel/drivers/bin/: para drivers del sistema.
  • /boot/home/config/add-ons/kernel/drivers/bin/ : para los drivers add-on de usuario.

Los kernel drivers están apuntados por un enlace simbólico, localizado en:

  • /boot/beos/system/add-ons/kernel/drivers/dev/graphics

Y los driver de addons por parte del usuario están apuntados por un enlace simbólico, que está en:

  • /boot/home/config/add-ons/kernel/dev/graphics

Si surge algún problema con un determinado addon durante el inicio del sistema, puede accederse a una ventana de configuración presionando la barra espaciadora. Eligiendo “Safe Mode Options” | Disable User Addons” podremos continuar con la carga, esto no funciona en Haiku según he probado, pero si debe funcionar en BeOS.

Descripción en detalle de las rutinas del kernel driver

  1. init_hardware()– el sistema inicializa el kernel driver llamando a esta rutina durantre el inicio del sistema (startup). Esta rutina comprueba si bus del sistema está disponible, y si el dispositivo está presente.
  2. init_driver() – se ejecuta después de init_hardware(). init_driver() inicializa variables, como pueden ser, el nombre del dispositivo y abre el bus del sistema para su uso.
  3. publish_devices() – el sistema llama a todo el hardware del sistema que está disponible utilizando esta rutina. Los nombres son publicados como enlaces simbólicos en la carpeta /dev/. Este enlace simbólico apunta a la localización del driver.
  4. uninit_driver() – cuando el driver ya no es necesario, el sistema llama a uninit_driver() que liberará todos los recursos usados y cerrará todas las entradas al bus usadas por el driver.
  5. find_device() – devuelve todos los nombres de las rutinas asociados al “unique name”, y los deja preparados para su por parte del “drivers hooks”. Este “driver hooks” es el interfaz con el usuario, usado para acceder al driver en el kernel.

Interfaz para el Usuario

Una vez que el sistema operativo a inicializado el kernel driver, este está disponible para ser accesible utilizando las rutinas “hook”:

  • open_hook()
  • close_hook()
  • free_hook()
  • control_hook()
  • read_hook()
  • write_hook()

La instrucción open_hook()

La rutina open_hook() construye una información compartida con una estructura (struct) que puede ser accedida por todos los aceleradores (accelerants), contiene los ID de las tarjetas, el fabricante, las especificaciones y los valores de visibilidad si estos son necesarios.

La rutina close_hook()

Esta rutina cierra el  driver.

La rutina free_hook()

Cierra el kernel driver. El número de veces que el driver es abierto o cerrado queda almacenado en el log del sistema operativo, cuando el kernel driver se cierra por última vez se llama a free_hook(), destruyéndose además la información compartida en la estructura mencionada anteriormente.

La rutina control_hook()

Esta rutina se llama siempre que se quiera acceder al kernel_driver, otra función es activar o desactivar las rutinas de interrupción o ejecutar los comandos de los buses del sistema (PCI).

La rutina read_hook()

Esta rutina no se usa, devuelve el estado B_NOT_ALLOWEB.

La rutina write_hook()

Igual que read_hook, write_hook() devuelve el estado B_NOT_ALLOWEB.

 

A %d blogueros les gusta esto: