Un driver en Haiku OS consta de las siguientes partes esenciales:
1. Estructura del Módulo
Todo driver debe exportar una API específica que termina con driver_v1 para indicar la versión del API que soporta device_manager_introduction.rst:103-105 . La estructura básica incluye:
module_info: Información del módulo con nombre, flags y operaciones estándar haiku-module.h:50-54
driver_t: Estructura que define el nombre, métodos y tamaño del softc haiku-module.h:62-66
2. Funciones Obligatorias del Driver
El device manager espera las siguientes funciones de un módulo de driver device_manager_introduction.rst:70-101 :
supports_device(): Determina si el driver soporta un nodo de dispositivo padre dado
register_device(): Registra el nodo del dispositivo y puede reclamar recursos de I/O
init_driver(): Inicializa los recursos necesarios para el driver
uninit_driver(): Libera los recursos adquiridos por init_driver()
register_child_devices(): Registra nodos de dispositivos hijos o publica dispositivos
rescan_child_devices(): Se llama cuando se activa un rescaneo manual
device_removed(): Se llama cuando el dispositivo está por ser desregistrado
3. Funciones de Exportación Estándar
Los drivers deben exportar funciones estándar para integrarse con el sistema es1370.c:26-30 :
init_hardware(): Inicialización del hardware
init_driver(): Inicialización del driver
uninit_driver(): Limpieza del driver
publish_devices(): Publica los nombres de dispositivos disponibles
find_device(): Retorna los hooks del dispositivo
4. Device Hooks
Para publicar un dispositivo en /dev, el driver debe implementar hooks de dispositivo device_manager_introduction.rst:151-177 :
init_device(): Llamado cuando se abre el dispositivo por primera vez
uninit_device(): Llamado cuando se cierra el último descriptor
open(): Llamado al abrir el dispositivo
close(): Llamado al cerrar
free(): Libera estructuras de datos privadas
read() / write(): Operaciones de lectura/escritura
control(): Operaciones ioctl
select() / deselect(): Para I/O asíncrono
5. Ejemplo Práctico: Driver Gráfico
Los drivers gráficos como intel_extreme demuestran esta estructura driver.cpp:1-30 :
Incluyen headers necesarios (driver.h, device.h, lock.h)
Usan módulos del sistema (AGP, KernelExport, PCI)
Implementan todas las funciones requeridas
6. Gestión de Recursos
Los drivers deben manejar:
Memoria: Mapeo de registros del dispositivo, buffers DMA
Interrupciones: Registro de manejadores de interrupciones
Sincronización: Uso de mutexes y locks para acceso concurrente
Notas
La arquitectura de drivers de Haiku sigue un modelo jerárquico con un Device Manager central que coordina el descubrimiento, carga y comunicación entre drivers. Los drivers pueden ser de kernel (modo kernel) o tener componentes en espacio de usuario (como los accelerants en drivers gráficos). Para drivers de red, Haiku incluye una capa de compatibilidad con FreeBSD que permite usar drivers de FreeBSD con modificaciones mínimas haiku-module.h:102-122 .
Pasos para Agregar Nuevos Dispositivos al Driver Radeon
1. Agregar la Entrada del Dispositivo a la Lista de Soporte
El primer paso es agregar la información del nuevo dispositivo a la estructura kSupportedDevices en src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp driver.cpp:43-50 . Esta estructura define todos los dispositivos soportados con:
pciID: El ID PCI del dispositivo (device ID)dceMajorydceMinor: Versión del bloque de display (Display Controller Engine)chipsetID: Identificador del chipset (ej. RADEON_TAHITI, RADEON_POLARIS11)chipsetFlags: Flags como CHIP_STD, CHIP_IGP, CHIP_MOBILE, CHIP_APUdeviceName: Nombre comercial del dispositivo
Por ejemplo, para agregar una Radeon RX 6700 XT: driver.cpp:653
{0x73df, 13, 5, RADEON_NAVI, CHIP_STD, "Radeon RX 6700 XT"},
2. Verificar el Proceso de Detección
El driver detecta dispositivos mediante la función get_next_radeon_hd() que escanea el bus PCI driver.cpp:672-698 . Esta función:
- Itera sobre todos los dispositivos PCI
- Verifica que sea un dispositivo ATI/AMD de clase display/VGA
- Compara el
device_idcon la listakSupportedDevices - Retorna el índice del dispositivo si hay coincidencia
3. Inicialización del Driver
Durante init_driver(), el sistema: driver.cpp:730-807
- Obtiene el módulo PCI
- Busca todos los dispositivos soportados
- Para cada dispositivo encontrado:
- Crea un nombre de dispositivo (ej.
graphics/radeon_hd_010200) - Asigna memoria para
radeon_info - Copia la información del PCI y del chipset desde
kSupportedDevices - Almacena
pciID,deviceName,chipsetID,dceMajor,dceMinor, ychipsetFlags
- Crea un nombre de dispositivo (ej.
4. Consideraciones Importantes
Dispositivos Deshabilitados: Algunos dispositivos están comentados con #if 0 porque se sabe que no funcionan correctamente driver.cpp:369-372 . Esto es importante para evitar problemas conocidos.
Agrupación por Generación: Los dispositivos están organizados por:
- Nombre de marketing (ej. "Radeon HD 24xx - HD 42xx")
- Fecha de introducción
- Nombre código (ej. "Pele", "Southern Islands")
- Proceso de fabricación (ej. "28 nm")
- Familia del chip (ej. "Cape Verde", "Tahiti") driver.cpp:295-307
5. Proceso Completo de Ejemplo
Para agregar una nueva Radeon RX 560:
- Identificar el PCI ID: 0x67ff
- Determinar la familia: Polaris 11 (DCE 11.2)
- Agregar a la lista: driver.cpp:560
- Recompilar el driver
- Probar con el hardware real
6. Verificación del Soporte
El sistema verifica el soporte mediante: driver.cpp:679-694
- Compara
info.vendor_idconVENDOR_ID_ATI - Verifica que sea clase
PCI_displayy subclasePCI_vga - Busca coincidencia del
device_idenkSupportedDevices
Notes
El driver Radeon HD soporta tarjetas desde la serie X700 (2004) hasta las más recientes Navi (2020+) driver.cpp:40 . La arquitectura usa AtomBIOS para la inicialización del hardware. Si agregas un dispositivo nuevo, asegúrate de conocer su DCE (Display Controller Engine) versión y familia de chipset correctas, ya que esto afecta cómo el accelerant manejará el dispositivo. Algunos dispositivos pueden requerir código adicional en el accelerant (src/add-ons/accelerants/radeon_hd/) para funcionar completamente.
Wiki pages you might want to explore: