Prefacio
Introducción de Jon
Introducción de Alessandro
Introducción de Greg
El público de este libro
Organización del material
Información de base
Ejemplos del libro
Capítulo 1
Introducción a los controladores de dispositivos
El papel del controlador de dispositivos
Cómo dividir el núcleo
Módulos que pueden ser cargados
Clases de dispositivos y de módulos
Cuestiones de seguridad
Numeración de las versiones
Condiciones de la licencia
Cómo unirse a la Comunidad de Programación del Núcleo
Vista general del libro
Capítulo 2
Creación y ejecución de módulos
Instalación de un sistema de prueba
El Módulo Hola, mundo
Módulos del núcleo frente a aplicaciones
Espacio del usuario y espacio del núcleo
Concurrencia en el núcleo
El proceso actual
Algunos detalles más
Compilación y carga
Compilación de módulos
Carga y descarga de los módulos
Dependencia de las versiones
Dependencia de plataformas
La tabla de símbolos del núcleo
Preliminares
Inicialización y cierre
La función de limpieza
Errores durante la inicialización
Carreras en la carga de módulos
Parámetros del módulo
Acciones en el espacio del usuario
Referencia rápida
Capítulo 3
Controladores de caracteres
El diseño de scull
Números mayores y menores
La representación interna de los números de dispositivo
Asignación y liberación de números de dispositivo
Asignación dinámica de números mayores
Algunas estructuras de datos importantes
Operaciones de archivo
La estructura file
La estructura inode
Registro de dispositivos de caracteres
Registro de dispositivos con scull
El modo antiguo
Open y release
El método open
El método release
El uso de memoria de scull
Read y write
El método read
El método write
Readv y writev
Prácticas con los nuevos dispositivos
Referencia rápida
Capítulo 4
Técnicas de depuración
Utilidades de depuración en el núcleo
La depuración por impresión
Printk
Cómo redireccionar los mensajes de la consola
Registro de mensajes
Activación y desactivación de los mensajes
Limitación de tasa
Impresión de números de dispositivo
Depuración a través de la consulta
Utilización del sistema de archivos /proc
Incorporación de archivos en /proc
Una interfaz más antigua
Cómo crear el archivo /proc
La interfaz seq_file
El método ioctl
Depuración por vigilancia
Depuración de los fallos del sistema
Los mensajes oops
Fallos del sistema
Los depuradores y otras herramientas relacionadas
La utilización de gdb
El depurador del núcleo kdb
Los parches kgdb
El Puerto de Linux en modo de usuario
El Set de herramientas de seguimiento de Linux
Sondas Dinámicas
Capítulo 5
Concurrencia y condiciones de carrera
Los problemas de scull
La concurrencia y su gestión
Semáforos y exclusiones mutuas
La incorporación de semáforos en Linux
Utilización de los semáforos con scull
Semáforos de lectura y escritura
Finalizaciones
Cerrojos
Introducción a la API de los cerrojos
Los cerrojos y el contexto atómico
Las funciones de los cerrojos
Cerrojos de lectura y escritura
Trampas del bloqueo
Reglas ambiguas
Reglas de orden de los bloqueos
Bloqueo a gran escala frente a bloqueo a pequeña escala
Alternativas al bloqueo
Algoritmos sin bloqueo
Variables atómicas
Las operaciones de bits
Seqlock
La Lectura-copia-actualización
Referencia rápida
Capítulo 6
Operaciones avanzadas con controladores de caracteres
Ioctl
La elección de los comandos de ioctl
El valor de retorno
Los comandos predefinidos
Utilización del argumento ioctl
Capacidades y operaciones restringidas
La incorporación de los comandos de ioctl
El control de los dispositivos sin ioctl
El bloqueo de la entrada y salida de datos
Introducción a la suspensión
La suspensión simple
Operaciones de bloqueo y desbloqueo
Un ejemplo de bloqueo de entrada y salida de datos
La suspensión avanzada
Cómo se suspende un proceso
Las suspensiones manuales
Las esperas exclusivas
Los detalles de la activación
Historia Antigua: sleep_on
Cómo probar el controlador scullpipe
Poll y select
La interacción con read y write
La lectura de datos desde el dispositivo
La escritura en el dispositivo
La eliminación de los datos de salida pendientes
La estructura de datos subyacente
La notificación asíncrona
El punto de vista del controlador
La búsqueda de un dispositivo
La incorporación de llseek
El control del acceso a un archivo de dispositivo
Los dispositivos de apertura única
La restricción de acceso a un único usuario cada vez
El bloqueo de open como alternativa a EBUSY
La clonación del dispositivo para open
Referencia rápida
Capítulo 7
Tiempos, retrasos y trabajo aplazado
La medición de los intervalos de tiempo
Utilización del contador de jiffies
Registros específicos del procesador
Cómo saber el tiempo en un momento dado
El retraso de la ejecución
Los retrasos largos
Busy waiting
La cesión del procesador
Los tiempos de espera
Los retrasos cortos
Los cronómetros del núcleo
La API de los cronómetros
La incorporación de los cronómetros del núcleo
Tasklets
Las colas de trabajo
La cola compartida
Referencia rápida
Control del tiempo
Retrasos
Cronómetros del núcleo
Tasklets
Colas de trabajo
Capítulo 8
Asignación de memoria
Fundamentos de kmalloc
Argumento flags
Regiones de memoria
Argumento size
Caché adelantado
Un scull basado en cachés de bloque: scullc
Almacenes de memoria
get_free_page y similares
Un scull basado en páginas completas: scullp
La interfaz alloc_pages
vmalloc y similares
Un scull basado en direcciones virtuales: scullv
Variables per-CPU
Obtención de grandes búferes
Obtención de un búfer dedicado durante el arranque
Referencia rápida
Capítulo 9
Comunicación con el hardware
Puertos de E/S y memoria de E/S
Registros de E/S y memoria convencional
Uso de los puertos de E/S
Asignación de puertos de E/S
Manipulación de puertos de E/S
Acceso a los puertos de E/S desde el espacio de usuario
Funciones string
Pausa de E/S
Dependencia de las plataformas
Ejemplo de un puerto de E/S
Visión general del puerto paralelo
Controlador de muestra
Uso de la memoria de E/S
Asignación y direccionamiento de memoria de E/S
Acceso a la memoria de E/S
Puertos como memoria de E/S
Vuelta a short para la memoria de E/S
Memoria ISA por debajo de 1 MB
isa_readb y similares
Referencia rápida
Capítulo 10
Manejo de interrupciones
Preparación del puerto paralelo
Instalación de un controlador de interrupción.
La interfaz /proc
Autodetección del número de IRQ
Pruebas basadas en el núcleo
Pruebas basadas en nuestra propia implementación
Controladores de interrupción rápidos y lentos
Detalles del manejo de interrupciones en las plataformas x86
Implementación de un controlador de interrupción
Argumentos del controlador de interrupción y valores devueltos
Activación y desactivación de interrupciones
Desactivación de una interrupción individual
Desactivación de todas las interrupciones
Mitades del controlador de interrupción: superior e inferior
Tareas
Colas de trabajo
Interrupciones compartidas
Instalación de un controlador de interrupción compartido
Ejecución del controlador de interrupción
La interfaz /proc y las interrupciones compartidas
E/S manejadas con interrupciones
Ejemplo de escritura de un búfer
Referencia rápida
Capítulo 11
Tipos de datos del núcleo
Uso de los tipos C estándar
Asignación de un tamaño explícito a los objetos de datos
Tipos específicos de la interfaz
Otros asuntos de portabilidad
Intervalos de tiempo
Tamaño de página
Orden de los bytes
Alineación de datos
Punteros y valores de error
Listas vinculadas
Referencia rápida
Capítulo 12
Controladores PCI
La interfaz PCI
Direccionamiento PCI
Tiempo de arranque
Registros e inicialización de la configuración
MODULE_DEVICE_TABLE
Registro de un controlador PCI
Pruebas PCI a la vieja usanza
Activación del dispositivo PCI
Acceso al espacio de configuración
Acceso a los espacios de E/S y memoria
Interrupciones PCI
Abstracciones de hardware
Un vistazo al pasado: ISA
Recursos de hardware
Programación ISA
La especificación Plug-and-Play
PC/104 y PC/104+
Otros buses de PC
MCA
EISA
VLB
SBus
NuBus
Buses externos
Referencia rápida
Capítulo 13
Controladores USB
Fundamentos de los dispositivos USB
Extremos
Interfaces
Configuraciones
USB y Sysfs
Urbs USB
struct urb
Creación y destrucción de urb
Urbs de interrupción (interrupt)
Urbs masivos (bulk)
Urbs de control (control)
Urb isócronos
Envío de los urb
Finalización de urb: manejador de finalización de retrollamada
Cancelación de urb
Programación de controladores USB
Dispositivos soportados por un controlador
Registro de controladores USB
Detalles de probe y disconnect
Envío y control de un urb
Transferencias USB sin urb
usb_bulk_msg
usb_control_msg
Otras funciones USB de datos
Referencia rápida
Capítulo 14
El modelo de dispositivos de Linux
Kobjects, Ksets y Subsistemas
Fundamentos de kobject
kobjects incrustados
Inicialización de un kobject
Manipulación del contador de referencia
Funciones de liberación y tipos de kobject
Jerarquías de los kobjects, ksets y subsistemas
Ksets
Operaciones con los ksets
Subsistemas
Operaciones sysfs de bajo nivel
Atributos predeterminados
Atributos no predeterminados
Atributos binarios
Enlaces simbólicos
Creación de eventos hotplug
Operaciones hotplug
Buses, dispositivos y controladores
Buses
Registro del bus
Métodos de bus
Iteraciones en dispositivos y controladores
Atributos del bus
Dispositivos
Registro del dispositivo
Atributos de dispositivos
Incrustación de estructuras de dispositivos
Controladores de dispositivos
Incrustación de la estructura del controlador
Clases
La interfaz class_simple
La interfaz de clase completa
Gestión de clases
Dispositivos de clase
Interfaces de clase
Unión de todos los conceptos anteriores
Incorporación de un dispositivo
Eliminación de un dispositivo
Incorporación de un controlador
Eliminación de un controlador
Hotplug
Dispositivos dinámicos
La utilidad /sbin/hotplug
IEEE1394 (FireWire)
Redes
PCI
Entrada
USB
SCSI
Estaciones de acoplamiento portátiles (laptop docking stations)
S/390 y zSeries
Empleo de /sbin/hotplug
Linux hotplug scripts
udev
Firmware
La interfaz de firmware del núcleo de Linux
Funcionamiento de firmware
Referencia rápida
Kobjects
Operaciones sysfs
Buses, dispositivos y controladores
Clases
Firmware
Capítulo 15
Direccionamiento de la memoria y DMA
Gestión de la memoria en Linux
Clases de direcciones
Direcciones y páginas físicas
Memoria alta y memoria baja
Mapas de memoria y struct page
Tablas de páginas
Áreas de memoria virtual
Ls estructura vm_area_struct
Mapa de memoria del proceso
Operación del dispositivo mmap
La función remap_pfn_range
Una implementación simple
Adición de operaciones a la VMA
Direccionamiento de memoria con nopage
Redireccionamiento de regiones de E/S específicas
Redireccionamiento de la RAM
Redireccionamiento de RAM con el método nopage
Redireccionamiento de direcciones virtuales del núcleo
E/S directa
E/S asíncrona
Ejemplo de E/S asíncrona
Acceso directo a memoria
Transferencia de datos DMA
Asignación del búfer DMA
Asignación manual (do-it-yourself)
Direcciones de bus
Capa DMA genérica
Cómo tratar con hardware complicado
Direccionamientos DMA
Configuración de direccionamientos DMA coherentes
Almacenes DMA (DMA pools)
Configuración de direccionamientos DMA secuenciales
Direccionamientos secuenciales single-page
Direccionamientos scatter-gather
Direccionamientos PCI de ciclos de doble dirección
Ejemplo de direccionamiento DMA para PCI
DMA para dispositivos ISA
Registro de operaciones DMA
Comunicación con el controlador DMA
Referencia rápida
Material introductorio
Implementación de mmap
Implementación de E/S directa
Acceso directo a memoria (DMA)
Capítulo 16
Controladores de bloque
Registro del controlador de bloque
El registro
Registro del disco
La inicialización en sbull
El tamaño de los sectores
Operaciones del dispositivo de bloque
Los métodos open y release
Soporte de medios extraíbles
El método ioctl
Procesamiento de peticiones
Introducción al método request
Un método request sencillo
Las colas de peticiones
La estructura request
Funciones de finalización de peticiones
Otros datos de interés
Preparación anticipada del comando
Tagged Command Queueing (TCQ)
Referencia rápida
Capítulo 17
Controladores de red
Cómo diseñar snull
Asignación de números IP
La transmisión física de paquetes
Conectando con el núcleo
Registro de dispositivos
Inicialización de los dispositivos
Descarga del módulo
La estructura net_device en detalle
Información general
Información del hardware
Información de la interfaz
Métodos para dispositivos
Campos de utilidad
Cómo abrir y cerrar la interfaz
Transmisión de paquetes
Control de la simultaneidad en las transmisiones
Tiempos de espera de las transmisiones
E/S scatter-gather
Recepción de paquetes
Controlador de interrupción
Mitigación de interrupciones de recepción
Cambios en el estado del enlace
Búferes de socket
Los campos más relevantes
Funciones de los búferes de socket
Resolución de la dirección MAC
ARP y Ethernet
Cómo anular ARP
Encabezados no Ethernet
Personalización de los comandos ioctl
Información estadística
La multidifusión
Soporte del núcleo para la multidifusión.
Ejemplo de implementación típica
Algunos datos importantes
Soporte de MII
Soporte de ethool
Netpoll
Referencia rápida
Capítulo 18
Controladores TTY
Un controlador tty pequeño
La estructura struct termios
Punteros de función tty_driver
open y close
El flujo de datos
Otras funciones de almacenamiento en búfer
La función de lectura
Configuración de línea TTY
set_termios
tiocmget y tiocmset
ioctls
Gestión proc y sysfs de dispositivos TTY
La estructura tty_driver en detalle
La estructura tty_operations en detalle
La estructura tty_struct en detalle
Referencia rápida
Bibliografía
Monografías
El núcleo de Linux
Diseño y estructura de Unix
Sitios Web
Con la última versión del núcleo de Linux se ha conseguido racionalizar y simplificar numerosas acciones comunes vinculadas al uso de controladores en esta plataforma, como las tareas plug and play, la interacción con el espacio de usuario a través del sistema de archivos sysfs, o la gestión de varios dispositivos en buses estándar.
Esta obra constituye una referencia esencial para todos aquellos que deseen utilizar y periféricos de ordenador con Linux, implementar nuevas opciones de hardware o simplemente estén interesados en la programación del núcleo en general. Completamente actualizada para la versión 2.6.10 del núcleo, contiene información inédita hasta ahora sobre el modo de programar drivers para una gran variedad de dispositivos.
Con tan sólo unos conocimientos básicos, podrá aprender rápidamente desde cómo escribir controladores para dispositivos de caracteres a dispositivos de bloque e interfaces de red de una manera realmente intuitiva, mediante numerosos ejemplos que podrá compilar y ejecutar sin recurrir a ningún tipo especial de hardware. Cubre ampliamente los subsistemas PCI, USB y tty (terminal), además de lo imprescindible para descubrir el modo en que un sistema operativo desempeña sus tareas, ofreciendo nuevas percepciones sobre los espacios de dirección, los eventos asíncronos y la E/S. Desde el punto de vista técnico, este manual le ofrece un acercamiento único tanto al interior del núcleo como a las elecciones de diseño tomadas por los programadores de Linux en el área de desarrollo de drivers.
© 2001-2024 Fundación Dialnet · Todos los derechos reservados