Creacion Drivers Usb

  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Creacion Drivers Usb as PDF for free.

More details

  • Words: 1,943
  • Pages: 23
Diseño de computadores

Creación de drivers para dispositivos USB

Ingeniería Técnica de Informática de Gestión Universidad de Jaén Profesor: Luis Miguel Nieto Nieto Rafa Muñoz Cárdenas

Contenidos 1. USB 1.1. Descriptores de un dispositivo 1.2. Comunicación con dispositivo 1.3. Modos de transferencia de información 2. Kernel vs. Libusb 3. Introducción a Usbfs 3.1. Libusb 4. Creación de un driver de ratón 5. Otros ejemplos de drivers 5.1. Ingeniería inversa 5.2. Lanzamisiles 6. Bibliografía Enero 2009

Rafa Muñoz Cárdenas

2

1. USB El Universal Serial Bus es un puerto que sirve para conectar periféricos a una computadora. Fue creado en 1996 por siete empresas: IBM, Intel, Northern Telecom, Compaq, Microsoft, Digital Equipment Corporation y NEC. Objetivos: Permitir la conexión de periféricos en una sola interfaz de socket estandarizada. Mejorar la capacidad “plug-and-play” (permitiendo así el “hot swapping”). Suministrar a través del mismo puerto energía a dispositivos de bajo consumo. 4 versiones: 1.0: Tasa de transferencia de hasta 1'5 Mbps (192 KB/s). Utilizado en teclados, ratones y joysticks. 1.1: Tasa de transferencia de hasta 12 Mbps (1'5 MB/s). 2.0: Tasa de transferencia de hasta 480 Mbps (60 MB/s). 3.0: Tasa de transferencia de hasta 4.8 Gbps (600 MB/s).

Enero 2009

Rafa Muñoz Cárdenas

3

1.1. Descriptores de un dispositivo Son bloques de información que permiten al host aprender características del periférico. Los descriptores más importantes son los siguientes: Descriptor de dispositivo: Contiene información básica del dispositivo. Descriptor de configuración: Representan el estado del dispositivo (activo, standby, inicialización) y su configuración básica (potencia, nº de interfaces, etc). Descriptor de interfaz: Contiene identificador de interfaz, número de endpoints de interfaz, etc. Un dispositivo USB puede consistir en varios sub-dispositivos lógicos (cada uno tendrá una interfaz). Por ejemplo: una webcam con micrófono incorporado (interfaz vídeo+interfaz audio). Es necesario un driver por cada interfaz. Descriptor de endpoint: Describe endpoints distintos del 0.

Enero 2009

Rafa Muñoz Cárdenas

4

1.2. Comunicación con dispositivo Esta comunicación se realiza a través de pipes (canales lógicos). Los pipes son conexiones del anfitrión al endpoint. El endpoint es el buffer desde el cual los datos entran o salen del dispositivo. Sólo será posible acceder a los datos de los descriptores anteriormente explicados a través de endpoints. Por ejemplo: para acceder a la configuración accedemos al endpoint 0. Dos tipos de transferencia unidireccional: IN (dispositivo a PC) o OUT (PC a dispositivo).

Enero 2009

Rafa Muñoz Cárdenas

5

1.3. Modos de transferencia de información También denominados como tipos de endpoints. Tipos: De control: Los endpoints de control son usados para controlar el dispositivo USB asíncronamente. P.e.: enviar comandos o pedir información de estado del periférico. Todo dispositivo debe tener este “endpoint 0”, usado para inicializar el periférico al conectarlo. De interrupción: El host solicita periódicamente pequeños paquetes de datos de tamaño fijo al dispositivo. El dispositivo siempre tiene que esperar a ser atendido. Se usa para ratones y teclados normalmente. Bulk: Transfieren grandes cantidades de datos. Con ella se asegura que los datos llegan siempre a su destino. Se usa para almacenamiento de datos o impresoras. Isochronous: Transfieren grandes cantidades de datos. No se garantiza la llegada de los datos a su destino. Se usa para dispositivos en tiempo real de vídeo o audio.

Enero 2009

Rafa Muñoz Cárdenas

6

2. Kernel vs. Libusb Nuestro sistema no es capaz de manejar un periférico USB => Escribir un driver. Alternativas al escribir drivers: Kernel driver Drivers centralizados en el núcleo. Buena velocidad y rendimiento. Soporta cualquier dispositivo complejo. Flexibilidad Pequeños cambios para otras arquitecturas (p.e: ARM). No portable a otros SO. Programación muy compleja.

Enero 2009

Rafa Muñoz Cárdenas

7

2. Kernel vs. Libusb Libusb driver Fácil de programar. Esconde detalles innecesarios al programador. Reduce el tamaño de los programas de forma notable. Código portable a otras plataformas. Drivers dispersos por internet (escasos grandes repositorios). La comunicación con periféricos es más lenta respecto a drivers en kernel. No válida para periféricos complejos.

Enero 2009

Rafa Muñoz Cárdenas

8

3. Introducción a Usbfs Usbfs es un sistema de archivos diseñado específicamente para periféricos USB y está incluido en el kernel Linux. Recopila información de todos los dispositivos conectados al PC. Evita escribir drivers como módulos en kernel. Los drivers son ejecutados en espacio de usuario (no root). Identifica los dispositivos y crea sus archivos asociados aunque su driver no haya sido creado aún. Para simplificar aún más la programación sobre Usbfs, podemos hacer uso de las librerías Libusb (C/C++) y jUSB (Java). Ambas corren sobre esta capa software en sistemas GNU/Linux.

Enero 2009

Rafa Muñoz Cárdenas

9

3.1. Libusb Ideal para dispositivos sencillos: cámaras, teclados, ratones, scanners, impresoras... Multiplataforma: GNU/Linux, *BSD, Mac OS X y Win32. Funciona en espacio de usuario => Fácil de depurar. A continuación se muestra un ejemplo de información de un ratón recopilada por Usbfs sobre un ratón:

Enero 2009

Rafa Muñoz Cárdenas

10

3.1. Libusb $lsusb -v Bus 002 Device 004: ID 046d:c001 Logitech, Inc. N48/M-BB48 [FirstMouse Plus] Device Descriptor: ...... idVendor 0x046d Logitech, Inc. idProduct 0xc001 N48/M-BB48 [FirstMouse Plus] ...... bNumConfigurations 1 Configuration Descriptor: ...... bNumInterfaces 1 ...... (Bus Powered) Remote Wakeup MaxPower 50mA Interface Descriptor: ...... bNumEndpoints 1 bInterfaceClass 3 Human Interface Device BinterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 2 Mouse iInterface 0 ...... Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes BInterval 10

Enero 2009

Rafa Muñoz Cárdenas

11

4. Creación de un driver de ratón Observando la salida de “lsusb -v” podemos empezar a crear nuestro driver usando la librería Libusb. raton.c: // Estos datos dependeran del dispositivo #define VENDOR 0x046d #define PRODUCT 0xc001

Recorremos los buses buscando el dispositivo anteriormente definido: static struct usb_device *find_device(const uint16_t &vendor, const uint16_t &product) { struct usb_bus *bus; struct usb_device *dev; struct usb_bus *busses; usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); // Recorremos todos los buses for (bus = busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if ((dev->descriptor.idVendor == vendor) && (dev->descriptor.idProduct == product)) { return dev; } } } return NULL; }

Enero 2009

Rafa Muñoz Cárdenas

12

4. Creación de un driver de ratón Ahora declaramos las estructuras del dispositivo y lo buscamos usando la función anteriormente declarada: int main() { struct usb_device *dev; struct usb_dev_handle *udev; dev = find_device(VENDOR, PRODUCT);

Abrimos dispositivo y deshabilitamos driver si es que estaba funcionando antes: udev = usb_open(dev); usb_detach_kernel_driver_np(udev, dev->config->interface->altsetting->bInterfaceNumber);

Reservamos interfaz para nuestra aplicación: reserva = usb_claim_interface(udev, 0);

Vamos a leer las interrupciones del ratón: // Monitorizamos hasta que no pulsemos boton derecho e izquierdo a la vez (3 0 0 0) while (data[0] != 3) { data[0] = data[1] = data[2] = data[3] = 0; // (0 0 0 0) intr = usb_interrupt_read(udev, 0x81, data, 4, 0); // Leemos 4 bytes del dispositivo usando interrupt_read for (i = 0; i < 4 && intr > 0; i++) { printf("%d ", data[i]); } printf("\n"); usb_clear_halt(udev, 0x81); // Reseteamos dispositivo para evitar que se sigan enviando // los mismos bytes despues de hacer click }

Enero 2009

Rafa Muñoz Cárdenas

13

4. Creación de un driver de ratón Terminamos y cerramos la comunicación con el periférico: usb_release_interface(udev, 0); usb_close(udev);

Enero 2009

Rafa Muñoz Cárdenas

14

4. Creación de un driver de ratón Probamos el programa: $ g++ -Wall -W raton.c -o driver_raton -L/usr/lib/ -lusb $ sudo ./driver_raton Buscando raton USB... ¡Encontrado! Deshabilitando driver de raton... Estado de solicitud de interfaz: 0 Protocolo de dispositivo: 0 Longitud de descriptor: 18 Tipo de descriptor: 1 Numero de endpoints: 1 Clase de interfaz: 3 Protocolo: 2 Numero de interfaz: 0 Nombre de fichero de dispositivo: 006 Fabricante: Logitech Nombre del producto: USB Mouse Numero de serie de dispositivo: ? Direccion de endpoint: 0x81 0 -1 0 0 0 -2 0 0 0 -1 0 0 0 -1 -1 0 0 -1 0 0 0 -1 0 0 1000 3000 Cerrando dispositivo.

Enero 2009

Rafa Muñoz Cárdenas

15

5. Otros ejemplos de drivers Necesitamos crear drivers de dispositivos complejos a los que hay que enviar señales de control para poder interactuar con ellos o URB's. No disponemos de documentación sobre su funcionamiento, por lo que necesitaremos realizar ingeniería inversa sobre drivers existentes (de Windows la mayoría).

Enero 2009

Rafa Muñoz Cárdenas

16

5.1. Ingeniería inversa Un programa conocido para “espiar” la información que circula por los buses USB es SnoopyPro. El procedimiento para capturar información revelante es el siguiente: 1. Iniciamos SnoopyPro y señalamos la interfaz a monitorizar. 2. Realizamos una acción simple con el dispositivo. 3. Guardamos la salida obtenida de realizar la acción simple. 4. Volvemos a realizar la acción simple con el periférico reiniciado para asegurarnos y guardamos de nuevo el log con la salida.

Enero 2009

Rafa Muñoz Cárdenas

17

5.1. Ingeniería inversa Ejemplo de i. inversa de dispositivo Cada comando enviado al dispositivo requiere 3 mensajes de control: El primero son todo ceros, probablemente como señal de que una orden va a llegar. En el segundo mensaje vemos que el buffer tiene el valor 0x00000008, y el endpoint para escribir el buffer es el 0 (0x00). Finalmente un mensaje con todo ceros para no repetir infinitamente el segundo mensaje.

Esta secuencia de mensajes viene de mover hacia la derecha un dispositivo a través de un programa para Windows proporcionado por el fabricante.

Enero 2009

Rafa Muñoz Cárdenas

18

5.2. Lanzamisiles El ejemplo anterior correspondía a un lanzamisiles... de juguete :) Si continuamos monitorizando los movimientos del lanzamisiles vemos que: Moviéndolo hacia arriba el contenido del buffer es 0x00000001. A menos que se envíe un comando stop (0x00000000), se mantiene ejecutando continuamente el último comando enviado. Continuamos la monitorización y ya podemos escribir: #define ML_STOP #define ML_ARR #define ML_ABA #define ML_IZQ #define ML_DER #define ML_FUEGO

0x00 0x01 0x02 0x04 0x08 0x10

Si continuamos moviendo el lanzamisiles hacia un lado y llega a su ángulo máximo de giro, detectamos que aparecen los siguientes bytes en el buffer del endpoint de interrupciones (de tipo IN): #define ML_MAX_ARR #define ML_MAX_ABA #define ML_MAX_IZQ #define ML_MAX_DER

Enero 2009

0x80 0x40 0x04 0x08

/* 80 00 00 00 00 00 00 00 */ /* 40 00 00 00 00 00 00 00 */ /* 00 04 00 00 00 00 00 00 */ /* 00 08 00 00 00 00 00 00 */

Rafa Muñoz Cárdenas

19

5.2. Lanzamisiles Otros datos interesantes extraídos: Buffer de transferencia de 8 bytes. Request type=0x21. Request=0x9. Value=0x200. Index: “1” para el primer y tercer mensaje y “0” para el mensaje segundo.

Enero 2009

Rafa Muñoz Cárdenas

20

5.2. Lanzamisiles Ahora podríamos ser capaces de crear nuestro driver para controlar el lanzamisiles. int send_message(char* msg, int index) { int j = usb_control_msg(launcher, 0x21, 0x9, 0x200, index, msg, // movimiento arriba/derecha/etc. 8, //bytes 1000); // timeout return j; } void movement_handler(char mov) { char msg[8]; msg[0] = 0x0; msg[1] = 0x0; msg[2] = 0x0; msg[3] = 0x0; msg[4] = 0x0; msg[5] = 0x0; msg[6] = 0x0; msg[7] = 0x0;

}

int deally = send_message(msg, 1); // enviamos ceros msg[0] = mov; deally = send_message(msg, 0); // enviamos movimiento deally = send_message(msg, 1); // enviamos ceros

Para cualquier movimiento excepto disparar, sería tan fácil como: movement_handler(ML_ARR);

Aquí podemos ver una demostración del funcionamiento de este juguete.

Enero 2009

Rafa Muñoz Cárdenas

21

6. Bibliografía

1. USB http://en.wikipedia.org/wiki/USB http://free-electrons.com/doc/linux-usb.pdf http://www.tech-pro.net/intro_usb.html http://www.fujitsu.com/downloads/EU/es/soporte/discosduros/UnpaseoporUSBMSD.pdf http://catarina.udlap.mx/u_dl_a/tales/documentos/lep/ordaz_g_r/capitulo2.pdf Linux Device Drivers, Third Edition (O'Reilly): http://lwn.net/Kernel/LDD3/ http://www.lrr.in.tum.de/Par/arch/usb/download/usbdoc/usbdoc-1.32.pdf 2. Kernel vs. Libusb http://www.freesoftwaremagazine.com/articles/drivers_linux?page=0%2C0 http://www.linuxquestions.org/questions/linux-kernel-70/kernel-driver-vs-libusb-662647/ http://www.nabble.com/Write-Linux-USB-Driver-td14913265.html 3. Introducción a Usbfs http://www.linuxforums.org/forum/linux-tutorials-howtos-reference-material/10865-develop http://libusb.wiki.sourceforge.net/ http://en.wikipedia.org/wiki/Libusb http://www.linux-usb.org/USB-guide/x173.html Enero 2009

Rafa Muñoz Cárdenas

22

6. Bibliografía

4. Creación de un driver de ratón http://www.linuxjournal.com/article/7466 http://www.cs.indiana.edu/~bpisupat/work/usb.html http://www.linuxjournal.com/article/6396 http://xianfengdesign.blogspot.com/2007/02/linux-usb-input-subsystem.html 5. Otros ejemplos de drivers: http://www.linuxquestions.org/questions/linux-hardware-18/driver-help-with-libusb-512040/ http://matthias.vallentin.cc/2007/04/writing-a-linux-kernel-driver-for-an-unknown-usb-devic http://scott.weston.id.au/software/pymissile/ http://www.jespersaur.com/drupal/book/export/html/21 http://www.amctrl.com/rocketlauncher.html

Enero 2009

Rafa Muñoz Cárdenas

23

Related Documents

Drivers
August 2019 51
Usb
April 2020 22
Drivers
November 2019 43
Drivers
April 2020 39
Usb
May 2020 17