Logo de AulaDigital

PCMCIA Como 7

Linux PCMCIA COMO : Trucos para depurar e información de programación Página siguiente Página anterior Índice general

7. Trucos para depurar e información de programación

7.1 Envío de informes de bugs que son de utilidad

La mejor forma de informar de bugs es usar las listas de mensajes de HyperNews en el servidor web de Linux PCMCIA. De este modo, otras personas podrán ver los problemas actuales (y reparaciones o trabajos relacionados, si están disponibles). He aqui algunas cosas que se deben incluir en los informes de bugs:

  • El tipo de sistema, y la salida del comando probe.
  • Qué tarjetas PCMCIA está usando.
  • Su versión del kernel de Linux, y la versión del controlador PCMCIA.
  • Cualquier cambio que haya hecho a los archivos de inicio en /etc/pcmcia, o al script de inicio de PCMCIA.
  • Todos los mensajes relacionados con PCMCIA en el registro de su sistema.

Todos los módulos PCMCIA y el demonio cardmgr envían mensajes de estado al registro del sistema, que estará normalmente en sitios como /var/log/messages o /usr/adm/messages. Este archivo debe ser el primer lugar a comprobar cuando se esté rastreando un problema. Cuando envíe una notificación de bug, incluya siempre el contenido de este archivo. Si tiene problemas para encontrar los mensajes de su sistema, revise /etc/syslog.conf para ver cuantas clases diferentes de mensajes se manejan.

Antes de enviar una notificación de bug, por favor asegúrese que no esté usando una copia obsoleta del paquete de controladores. Aunque resulte gratificante leer informes sobre un bug que ya he reparado, no supone un uso particularmente constructivo de mi tiempo.

Si no tiene acceso a web, puede enviarme los informes de bugs a dhinds@hyper.stanford.edu. Sin embargo, prefiero que sean introducidos en mi servidor web, así pueden ser vistos por otros.

7.2 Interpretación de los informes generados por los traps del kernel

Si su problema incluye un fallo del kernel, el vaciado del registro del fallo sólo es útil si puede traducir la dirección del error, EIP, o algo semejante. Las versiones recientes de klogd intentan traducir las direcciones de fallos basándose en el mapa actual de símbolos del kernel, pero puede que no funcione si el error se produce en un módulo, o si el problema es lo bastante severo como para que que klogd no pueda terminar de escribir la información del fallo en el registro del sistema.

Si se localiza en el kernel principal, la dirección de fallo puede encontrarse en el archivo System.map. El cual puede estar instalado en /System.map o en /boot/System.map. Si está en un módulo, el comando nm proporciona la misma información; sin embargo, la dirección del fallo necesita ajustarse basándose en la dirección de carga del módulo. Digamos que experimenta el siguiente fallo del kernel:

       Unable to handle kernel NULL pointer dereference
       current->tss.cr3 = 014c9000, %cr3 = 014c9000
       *pde = 00000000
       Oops: 0002
       CPU:    0
       EIP:    0010:[<c2026081>]
       EFLAGS: 00010282

La dirección de fallo es 0xc2026081. Si buscamos en System.map, vemos que esto está más allá de los límites del kernel, por ejemplo, es un módulo del kernel. Para determinar qué módulo, revise la salida de ksyms -m | sort

       Address   Symbol                            Defined by
       c200d000  (35k)                             [pcmcia_core]
       c200d10c  register_ss_entry                 [pcmcia_core]
       c200d230  unregister_ss_entry               [pcmcia_core]
                 ...
       c2026000  (9k)                              [3c574_cs]
       c202a000  (4k)                              [serial_cs]

Así, 0xc2026081 está en el módulo 3c574_cs con un desplazamiento de 0x0081 desde el inicio del módulo. Todavía no podemos ver más allá de este desplazamiento en 3c574_cs.o: cuando el kernel carga un módulo, inserta un encabezado en la dirección de carga del mismo, así el inicio real se desplaza desde la dirección mostrada en ksyms. El tamaño del encabezado varía con la versión del kernel: para encontrar el tamaño en su kernel, busque un módulo que exporte símbolos (como pcmcia_core), y compare la dirección del símbolo con la salida de nm para ese mismo símbolo. En este ejemplo, register_ss_entry se carga con un desplazamiento de 0xc200d10c - 0xc200d000 = 0x010c, mientras que nm pcmcia_core.o muestra el desplazamiento como 0x00c0, así que el tamaño del encabezado es 0x010c - 0x00c0 = 0x004c bytes.

Regresando a 3c574_cs.o, nuestro desplazamiento de fallo es 0x0081, y restando el encabezado 0x004c, el desplazamiento real del módulo es 0x0035. Ahora comprobando el resultado de un nm 3c574_cs.o | sort, observamos:

  0000002c d if_names
  0000002c t tc574_attach
  00000040 d mii_preamble_required
  00000041 d dev_info

El fallo se localiza en tc574_attach().

En este ejemplo, el fallo no causó un congelamiento total del sistema, así que ksyms puede ejecutarse después de haber tenido lugar el fallo. En otros casos, puede que tenga que deducir indirectamente las direcciones de carga del módulo. La misma secuencia de eventos cargará normalmente los módulos en el mismo orden y en las mismas direcciones. Si se produce un fallo cuando se inserta cierta tarjeta, obtenga la salida de ksyms antes de insertar la tarjeta, o con una tarjeta diferente insertada. Puede cargar manualmente los módulos controladores de la tarjeta con insmod y ejecutar ksyms antes de insertarla.

Para profundizar, consulte man insmod, man ksyms, y man klogd. En el árbol de los fuentes del kernel, Documentation/oops-tracing.txt también es relevante. He aquí unas cuantas pistas para depurar el kernel:

  • Dependiendo del error, puede ser útil traducir direcciones en el Trazado de llamadas, usando el mismo procedimiento para la dirección de error principal.
  • Para diagnosticar un congelamiento silencioso, pruebe provocar el problema con X desactivado, porque los mensajes del kernel se envían a la consola en texto, y no serán visibles bajo X.
  • Si mata a klogd muchos de los mensajes del kernel harán eco directamente a la consola de texto, el cual puede ser útil si el problema impide a klogd escribir en el registro del sistema.
  • Para hacer que todos los mensajes del kernel se envíen a la consola, para kernels 2.1.x, si existe /proc/sys/kernel/printk, hacer:
           echo 8 > /proc/sys/kernel/printk
    
  • La combinación de teclas <RightAlt><ScrLk> imprime un vaciado del registro en la consola de texto. Esto puede funcionar en caso de que el sistema esté o no completamente sin responder, y la dirección EIP puede interpretarse como fallo del kernel.
  • Para los kernels 2.1.x configurados con CONFIG_MAGIC_SYSRQ activado, se pueden activar varias funciones de emergencia por medio de las combinaciones especiales de las teclas <Alt><SysRq>, que están documentadas en Documentation/sysrq.txt dentro del árbol de los fuentes del kernel.

7.3 Primeros auxilios al depurar a bajo nivel

Los módulos PCMCIA contienen bastante código de depuración compilado de forma condicional. La mayor parte de este código está bajo el control de las definiciones del preprocesador de PCMCIA_DEBUG. Si no está definido, el código de depuración no se compilará. Si se establece a 0, se compilará pero no estará activo. Los números mayores especifican el incremento del nivel de detalle del registro. Cada módulo compilado con PCMCIA_DEBUG definido tendrá un parámetro entero, pc_debug, que controla el nivel de detalle de su salida. Esto puede ajustarse cuando se carga el módulo, así la salida puede controlarse en base a cada módulo sin necesidad de recompilar.

Su configuración por omisión para syslogd puede descartar los mensajes de depuración del kernel. Para asegurarse de que se están registrando, edite /etc/syslog.conf y compruebe que los mensajes kern.debug se registren en algún lugar. Consulte man syslog.conf para más detalles.

Hay algunas herramientas de depuración en el subdirectorio debug_tools dentro de la distribución de PCMCIA. Las utilidades dump_tcic y dump_i365 generan volcados completos de los controladores PCMCIA, y decodifican mucha de la información del registro. Son útiles si tiene acceso a una hoja con los datos del chip controlador correspondiente. El comando dump_cis (dump_tuples en las distribuciones pre-3.0.2) lista el contenido de la CIS (Card Information Structure) (Estructura de Información de Tarjeta), y decodifica algunos bits importantes. dump_cisreg muestra los registros de configuración local de una tarjeta.

El controlador de tarjetas de memoria memory_cs a veces también es útil para depurar problemas con PC Cards de 16 bits. Puede utilizarse con cualquier tarjeta, y no interfiere con otros controladores. Puede usarse para acceder directamente a los atributos de memoria o memoria común de cualquier tarjeta. De igual modo, con las tarjetas CardBus, el controlador memory_cb puede utilizarse con cualquier tarjeta de 32 bits, para dar acceso directo a los espacios de direcciones de esa tarjeta. Revise las páginas del manual para más información.

7.4 /proc/bus/pccard

A partir de los kernels 2.1.103, el paquete PCMCIA crea un árbol de información de estado bajo /proc/bus/pccard. La entrada memory muestra las posiciones de memoria para dispositivos PC Card en un formato similar a /proc/ioports. Cada socket tiene también su propio subdirectorio de entradas de estado. La entrada info identifica el controlador del host y describe sus características. La entrada exca es un volcado del registro ExCA compatible con Intel i82365sl que se configura para ese socket. Para los puentes CardBus, la entrada pci es el volcado del espacio de la configuración PCI del puente, y la entrada cardbus es el vaciado de los registros de configuración de CardBus.

7.5 Programación de controladores de servicios PCMCIA para nuevas tarjetas

El Linux PCMCIA Programmer's Guide constituye la mejor documentación acerca de la interfaz de los controladores. La última versión estará siempre disponible en hyper.stanford.edu en /pub/pcmcia/doc, o vía WWW en http://hyper.stanford.edu/HyperNews/get/pcmcia/home.html.

Con los dispositivos relativamente similares a los dispositivos ISA normales, probablemente pueda Vd. usar parcialmente controladores Linux existentes. En algunos casos, el tropiezo más grande será modificar un controlador existente que pueda manejar la inserción y extracción de dispositivos después del momento de iniciar. De los controladores actuales, el controlador de tarjeta de memoria es el único controlador autónomo, que no depende de otras partes del kernel de Linux para hacer la mayor parte del trabajo sucio.

En muchos casos, el mayor impedimento para soportar un nuevo tipo de tarjeta es el obtener información técnica por parte del fabricante. Puede ser difícil el encontrar a quién preguntar, o a quien explicar que información se necesita. Sin embargo, con pocas excepciones, es muy difícil, si no imposible, el implementar un controlador para una tarjeta sin información técnica por parte del fabricante.

He escrito un controlador modelo con muchos comentarios que explican bastante cómo el controlador se comunica con los Servicios de Tarjetas; lo encontrará en la distribución fuente de PCMCIA en clients/dummy_cs.c.

7.6 Sugerencias para los autores de controladores PCMCIA

He decidido que no es realmente factible para mi el distribuir todos los controladores de PCMCIA como parte del paquete PCMCIA. Cada controlador nuevo hace que el paquete principal sea incrementalmente más dificil de mantener, e incluir un controlador inevitablemente transfiere algo del trabajo de mantenimiento del autor del controlador hacia mí. En lugar de ello, decidiré caso por caso si se incluyen o no los controladores que sean contribuciones, basándome en la demanda de los usuarios y también en la facilidad de mantenerlos. Para los controladores que no se incluyen en el paquete principal, sugiero que los autores de los controladores adopten el esquema siguiente para empaquetar sus controladores de cara a su distribución.

Los archivos controladores deben acomodarse en el mismo esquema del directorio que utiliza la distribución fuente de PCMCIA, así el controlador puede ser desempaquetado en la parte más alta del árbol de los fuentes de PCMCIA. Debe incluir los archivos fuentes (en ./modules/), una página del manual (en ./man/), y los archivos de configuración (en ./etc/ ). El directorio más alto debe incluir también un archivo README.

El directorio de más alto nivel debe incluir un makefile, configurado para que make -f ... all y make -f ... install compilen el controlador e instalen los archivos apropiados. Si este archivo tiene una extensión .mk, será invocado automáticamente por el Makefile de más alto nivel para los destinos all e install. He aquí un ejemplo de cómo debe elaborarse un Makefile:

       # Un simple Makefile para un controlador de contribución
       FILES = sample_cs.mk README.sample_cs \
               modules/sample_cs.c modules/sample_cs.h \
               etc/sample etc/sample.opts man/sample_cs.4
       all:
               $(MAKE) -C modules MODULES=sample_cs.o
       install:
               $(MAKE) -C modules install-modules MODULES=sample_cs.o
               $(MAKE) -C etc install-clients CLIENTS=sample
               $(MAKE) -C man install-man4 MAN4=sample_cs.4
       dist:
               tar czvf sample_cs.tar.gz $(FILES)

Este Makefile usa los destinos de instalación que se definen en la versión 2.9.10 y versiones posteriores del paquete PCMCIA. Este makefile también incluye un destino dist para conveniencia del autor del controlador. Probablemente desee añadir un número de versión al final del nombre del paquete (por ejemplo, sample_cs-1.5.tar.gz). Una distribución completa puede ser similar a:

       sample_cs.mk
       README.sample_cs
       modules/sample_cs.c
       modules/sample_cs.h
       etc/sample
       etc/sample.opts
       man/sample_cs.4

De esta forma, cuando un controlador de contribución se desempaquete, se convierte en parte esencial del árbol de los fuentes de PCMCIA. Puede hacer uso de los archivos de encabezados de PCMCIA, así como también de la maquinaria para comprobar la configuración del sistema del usuario, y chequeo automático de dependencias, tal y como un controlador «normal».

Aceptaré controladores preparados de acuerdo a esta especificación y los colocaré en el directorio /etc/pcmcia/contrib en mi servidor FTP, hyper.stanford.edu. El archivo README en este directorio describirá cómo desempaquetar un controlador de contribución.

La interface de controlador no ha cambiado mucho a pesar del tiempo, y ha preservado casi siempre su compatibilidad con las versiones anteriores. Un controlador normalmente no necesitará actualizarse para revisiones menores en el paquete principal. Trataré de notificar a los autores de los controladores «externos» de los cambios que se requiera realizar a sus controladores.

7.7 Sugerencias para encargados de las distribuciones de Linux

Si su distribución tiene herramientas para configuración del sistema que quiera que sean compatibles PCMCIA, por favor, use los archivos *.opts en /etc/pcmcia para su «integración». Dichos archivos no serán modificados si un usuario compila e instala una nueva versión del paquete PCMCIA. Si modifica los scripts principales de configuración, una instalación fresca sobreescribirá silenciosamente sus scripts personalizados y romperá la conexión con sus herramientas de configuración. Contacte conmigo si no está seguro de cómo escribir un script de opciones apropiado, o si necesita características adicionales.

Resulta muy útil para los usuarios (y para mi) que documente cómo deriva su distribución del paquete PCMCIA que se describe en este documento. En particular, por favor documente los cambios al script de inicio y a los scripts de configuración. Si me manda la información apropiada, la incluiré en la sección Notas acerca de distribuciones de Linux específicas.

Cuando construya una distribución PCMCIA, considere el incluir los controladores aportados, que no son parte del paquete PCMCIA principal. Por razones de mantenimiento, estoy tratando de limitar el tamaño del paquete principal, añadiendo solamente controladores nuevos si considero que son de interés general. Los demás controladores se distribuirán por separado, como se describe en la sección anterior. La división entre controladores generales y separados es algo arbitraria y en parte histórica, y no debería implicar diferencia alguna en cuanto a calidad.


Página siguiente Página anterior Índice general