Trabajo de Doctorado

Anuncio
8QLYHUVLGDG3ROLWpFQLFDGH0DGULG
'HSDUWDPHQWRGH$UTXLWHFWXUD\7HFQRORJtDGH6LVWHPDV,QIRUPiWLFRV
FACULTAD DE INFORMÁTICA
Trabajo de
Doctorado
Manejador de tipo módulo para
la SCC-8530 en LINUX
Alumno: Jorge OCÓN ALONSO
Profesor: Juan ZAMORANO FLORES
Resumen
En el presente documento se describe el desarrollo de un manejador para una tarjeta de
comunicaciones serie en LINUX. Este desarrollo ha sido utilizado en proyectos reales
en sistemas que actualmente están funcionando. El manejador objeto de esta práctica
está actualmente funcionando en sistemas de tiempo real (equipos de FRQFHQWUDGRUHV
GHHVWDFLyQ) en los trenes de Buenos Aires.(TBA).
Palabras clave
Manejador, LINUX, Entradas y Salidas, RS-232
$JRVWR
'$76,830‹
F.I. t Campus de Montegancedo t Boadilla del Monte t 28660 Madrid t ESPAÑA t Tel: + 34 91 3367387 t Fax: + 34 91 3367373 t http://www.fi.upm.es/
,1752'8&&,21
48((6810$1(-$'25"
/$6&&'(=,/2*
/2602'8/26',1$0,&26
,16(5&,Ï1'(6,167$/$&,21'(/.(51(/
86$1'2(/0$1(-$'25
$1$/,6,6'(/&2',*25(/$7,92$/$//$0$'$,2&7/
CONCLUSIONES
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
,1752'8&&,21
Como es sabido, Linux es un sistema operativo multitarea diseñado por Linus
Torvalds y un equipo de colaboradores siguiendo estándares 326,;. Aunque
externamente y a nivel de programación ofrece un interfaz tipo 81,;, Linux ha sido
reescrito totalmente de nuevo, por lo que el código fuente está protegido por la licencia
*18, lo que permite a cualquier persona disponer del código fuente y utilizarlo de
forma totalmente gratuita. Esto, que de por sí constituye un gran atractivo para un
sistema operativo de cara a posibles desarrollos, es tan solo una más de sus cualidades.
Otros sistemas operativos (0LQL[, por ejemplo, del cual /LQX[ heredó parte del kernel)
fueron también desarrollados como sistemas libres, pero no llegaron a tener la
fiabilidad, la eficiencia en el uso de recursos ni la difusión de /LQX[. En este sentido, es
un hito en la historia de la Informática que merece ser reconocido, reconocimiento que
se hizo público al ser premiado como ³6LVWHPD RSHUDWLYR GHO DxR ´ por
,QIRZRUOG. Aunque originalmente diseñado para el mundo de los Pcs compatibles, que es el
entorno de mayor difusión, existen versiones de /LQX[ para diversas plataformas:
63$5& de 6810,&526<67(06 $/3+$ de '(&, versiones para procesadores
0RWRUROD, etc...
Debido a que es software libre,, y a que estamos hablando del sistema operativo
que probablemente mejor gestiona los recursos del PC actualmente, ha tenido gran
difusión no sólo en entornos universitarios, sino en entornos profesionales. Hoy en día,
un 30% de los servidores de Internet (Internet Sites) son PC que corren /LQX[ como
sistema operativo.
En torno al proyecto /LQX[ se han desarrollado paquetes de software, algunos de
los cuales son sencillamente versiones portadas de otros desarrollos de *18, y otros
muchos colaboraciones que se venden de forma semi-gratuita. También existen varias
compañías que venden distribuciones de /LQX[ (RedHat, Debian, Slackware), y otras se
dedican a dar soporte del sistema. En general, /LQX[ ha proporcionado el acceso de
forma gratuita a un sistema operativo (81,;) que estaba reservado a unos pocos.
En todo caso, el proyecto /LQX[ constituye una aportación sobresaliente al
desarrollo del software libre, y pese a no contar con una firma que lo soporte, la difusión
de /LQX[ es cada vez mayor, tanto en ambientes universitarios como profesionales.
Esta práctica explica el desarrollo de un manejador para una tarjeta de
comunicaciones serie en /LQX[. Este desarrollo ha sido utilizado en proyectos reales en
sistemas que actualmente están funcionando. Naturalmente, no hubiera sido posible este
desarrollo sin la existencia del software libre, y en particular sin la existencia de
Internet.
1
(1) Este galardón fue concedido a la distribución RED-HAT.
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
Sinceramente espero que el espíritu del libre intercambio de ideas y proyectos, y
la colaboración desinteresada entre ingenieros de todo el mundo vaya en aumento. Es
algo de lo que toda la sociedad en su conjunto, y los desarrolladores en particular, se
benefician.
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
48((6810$1(-$'25"
Los sistemas operativos clásicos (no aquellos específicamente diseñados para
tiempo real), establecen una frontera clara entre el.(51(/ del sistema operativo, que
gestiona los recursos (memoria, tiempo de &38, escritura y lectura en dispositivos, etc...
) y el resto de los procesos, procesos de usuario que generalmente trabajan con memoria
virtual, acceden a los dispositivos mediante el sistema operativo, y son periódicamente
puestos en ejecución y ‘swapped out’, es decir, hibernados por el kernel, que distribuye
la &38 entre los distintos procesos, de forma que el resultado sea un aparente
procesamiento en paralelo de varios procesos. En este sentido, podriamos decir que
existen básicamente dos tipos de software: el kernel, que reside permanentemente en la
memoria, y el resto de los procesos, cuya ejecución es controlada y manejada por el
kernel. Este esquema ha demostrado tener muchas ventajas, puesto que aquellos
procesos que intentan acceder a direcciones de memoria ajenas son inmediatamente
detectados por el kernel, y literalmente ‘expulsados’ del sistema. Como el acceso a los
recursos se realiza a través del kernel, éste puede detectar inter-bloqueos, llamadas con
parámetros erróneos, y en general, cualquier error de un proceso se puede aislar de
forma que no tenga consecuencias fatales para el conjunto del sistema. Cualquiera que
haya programado en 06'26 (que no sigue en absoluto este esquema) y un sistema
multitarea como 906 ó 81,; ha podido percatarse de esta diferencia: en 06'26, un
programa puede estar accediendo a cualquier posición de memoria tanto para lectura
como para escritura, y no se detecta una escritura en una posición de memoria ajena a no
ser que provoque una caída del programa (lo que en la mayoría de los casos genera una
caída de todo el sistema). En 906 ó 81,;, por el contrario, no ocurre esto, se detecta y
se expulsa de ejecución al proceso que realiza un acceso a zonas de memoria ajenas, con
lo que se facilita su depuración. Esto constituye además una buena protección contra los
virus informáticos, que siempre intentan acceder a los recursos del sistema de forma
inadvertida.
En sistemas más recientes se ha incorporado un tercer tipo de proceso,
denominado µSURFHVRGHWLHPSRUHDO¶, que está a medio camino entre la concepción de
proceso clásica y el propio kernel. Estos procesos tienen la posibilidad de poder fijar
plazos de tiempo muy cortos (en torno a los 10 milisegundos) para ser despertados por
el kernel. En otros sistemas se permite bajo ciertas condiciones que los procesos
accedan a posiciones de memoria real utilizando llamadas al sistema específicamente
diseñadas para esto (3) Estas extensiones son en realidad un intento de los fabricantes
de sistemas operativos de permitir que un proceso pueda cumplir con requisitos de
tiempo real de forma efectiva, sin que sea preciso para esto implementar un manejador.
Los manejadores son, como su nombre indica, aquellas partes del kernel
específicamente diseñadas para el manejo de determinados recursos (p. ej. una tarjeta de
comunicaciones, el disco, la unidad &'520, una tarjeta Ethernet, etc... ). Incorporan
toda la heurística del dispositivo específico que controlan, y naturalmente, son muy
dependientes del hardware: un manejador siempre está asociado al hardware que
controla, y una sustitución del hardware va asociada generalmente a una sustitución del
manejador, salvo que el nuevo hardware presente un interfaz compatible.
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
Al formar parte del kernel, los manejadores se distinguen por completo del
software de los procesos de usuario: No hacen llamadas al sistema operativo (puesto que
son parte de él), sino que en su lugar, utilizan una serie de rutinas del propio sistema
operativo que les permiten reservar memoria del kernel, acceder a memoria real,
bloquear o liberar las interrupciones de la &38, leer o escribir vectores de interrupción,
fijar plazos de tiempo muy breves (incluso por debajo de los 10 milisegundos) y acceder
a la memoria virtual de un proceso, entre otras. Estas rutinas no están disponibles para
los procesos normales, y son específicas del sistema operativo, por lo que lo primero
que debe de hacer un programador de un manejador es familiarizarse con esta librería de
rutinas del sistema. Uno no dispone de las rutinas típicas de librería para sacar datos por
pantalla ó leer del teclado, por lo que la depuración del manejador constituye una
experiencia diferente a la programación tradicional.
Estas ventajas frente a procesos de usuario en cuanto a accesibilidad de recursos
tienen a la vez el inconveniente de la fiabilidad: un manejador que se comporte de
forma errónea puede perfectamente bloquear por completo el sistema operativo,
causando una caida general de todo el sistema, con los peligros que ello conlleva
(perdida de ficheros, necesidad de reinstalar todo el sistema operativo de nuevo, etc... ).
Esto es una dificultad añadida para el desarrollo de los manejadores, que hace que
muchos programadores se planteen el desarrollo de manejadores con cautela, y que se
opte muchas veces por utilizar un proceso de tiempo real allí donde sea posible en lugar
de un manejador.
Existe un conjunto de puntos de entrada al manejador. Estos puntos de entrada
son hebras de código que el sistema operativo se encarga de activar cuando un proceso
usuario realiza una llamada al sistema operativo relacionada con el dispositivo del
manejador. Así por ejemplo cuando un proceso usuario solicita el envío de un paquete a
través de la red Ethernet de una máquina, existirá una zona de código en el manejador
de la tarjeta Ethernet que se activará, para hacer posible el envio de dicho paquete,
enviando los comandos precisos al dispositivo hardware a fín de que físicamente envíe
la trama correspondiente. Estos puntos de entrada pueden clasificarse de forma genérica
como:
3DUD DFFHGHU DO GLVSRVLWLYR Mediante el cual el proceso comunica al
manejador que desea acceder al dispositivo. El manejador puede así permitir el acceso,
realizando la asociación entre proceso y dispositivo, lo que le permite saber en todo
momento cual o cuales de los procesos están utilizando un dispositivo determinado. En
81,;, esta es la llamada RSHQ a un manejador.
3DUD OLEHUDU HO GLVSRVLWLYR El proceso comunica asi al manejador que ha
finalizado el acceso al dispositivo, con lo cual el manejador actualiza su tabla de
correspondencias entre procesos/dispositivos. A efectos el proceso deja de estar
asociado al dispositivo en cuestión, y el dispositivo queda libre para ser utilizado por
cualquier proceso en adelante. En 81,; esto se traduce en una llamada FORVH al
manejador.
(VFULWXUD Para almacenar, o enviar la información. En 81,;, son accesos tipo
ZULWH.
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
/HFWXUD Leer o recibir la información del dispositivo. En 81,;, son accesos
tipo UHDG
3DUDPHWUL]DU HO GLVSRVLWLYR Cambiar velocidad, Fijar paridad, especificar
protocolos, cambiar modo funcionamiento. Se realizan mediante llamadas LRFWO
2EWHQHUHOHVWDGRGHOGLVSRVLWLYR Obtener estadísticas. También son llamadas
LRFWO aunque existen algunas específicas.
Aunque forman parte del kernel, en 81,;, el interfaz para los procesos de
usuario del kernel es un fichero (siguiendo la filosofía de 81,;). El proceso que utiliza
el manejador lo abre mediante una llamada RSHQ contra este fichero, y obtiene un
identificador, que utiliza en las siguientes llamadas. Finaliza el acceso con una llamada
a FORVH. Este tratamiento es común para todos los sistemas 81,;.
Los manejadores en 81,;se clasifican en dos grandes grupos:
0DQHMDGRUHVGHPRGRFDUiFWHU
0DQHMDGRUHVGHPRGREORTXH
Estos dos grandes grupos se diferencian en el modo en que procesan la
información: en un manejador de tipo carácter la información se transfiere byte a byte,
es decir, tanto las lecturas como las escrituras se hacen de carácter en carácter
individualmente. En los manejadores de tipo bloque tanto las lecturas como las
escrituras se realizan por bloques o conjuntos de varios caracteres.
Un mismo dispositivo físico (p.ej. la unidad de cinta) puede tener dos
manejadores diferentes de tipo bloque y de tipo carácter. La elección de uno u otro por
parte del proceso se realizará siguiendo criterios de eficiencia, en función de sus
necesidades. Un manejado de tipo bloque puede permitir una mayor eficiencia en las
lecturas o escrituras, transfiriendo información de forma más rápida. Un manejador de
tipo caracter puede permitir al proceso trabajar con mayor grado de precisión en las
lecturas y/o escrituras.
Los manejadores en 81,; tienen dos números asociados llamados mayor y
menor (PDMRU and PLQRU). El número mayor es el que indica la versión del manejador
en cuestión. Permite detectar cambios de versión del manejador en el kernel, lo que es
muy importante puesto que una llamada a una función no soportada podria causar la
caída de todo el sistema. El numero menor identifica al dispositivo de forma unívoca (en
sistemas 6&6,, por ejemplo, el numero menor identifica la dirección 6&6, del
dispositivo en cuestión), de forma que el mismo software del manejador se utilice para
todos los dispositivos de ese tipo que haya en la máquina.
En los sistemas ´Plug-and-play´ actualmente en uso, al arrancar el sistema los
manejadores detectan automáticamente los dispositivos de su tipo que hay en la
máquina y los inicializan. Esto, que sin duda es una ventaja de cara a posibles
reconfiguraciones del sistema, presenta una dificultad añadida para el programador,
puesto que la rutina de detección del hardware debe de ser diseñada cuidadosamente.
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
Generalmente esta rutina accede a direcciones de memoria y/o vectores de interrupción
que utiliza el dispositivo hardware en el momento del arranque. Si el acceso provocase
una interrupción no contemplada por el kernel (lo que puede ocurrir dado que en ese
momento no se sabe aún la configuración del sistema), podríamos encontrarnos con una
caída general del sistema en el momento del arranque. De ahí que la rutina de detección
deba de estar diseñada cuidadosamente.
Los manejadores están generalmente incluidos en el kernel del sistema,
formando parte del mismo. Sin embargo, en algunos sistemas operativos (como en
/LQX[), existe la posibilidad de que existan como módulos independientes que se
carguen dinámicamente. Para ello es necesario que exista un cargador (ORDGHU) de
módulos del kernel, que se encarga de insertar el módulo en el momento en que se
solicita y quitarlo del kernel cuando sea preciso. Esto presenta la ventaja de que sólo se
carguen los manejadores de los dispositivos existentes, con lo cual el tamaño del kernel
se ve tremendamente reducido. El tamaño del kernel es importante puesto que reside por
completo en la memoria y por tanto la memoria real disponible para el sistema en
ejecución es la diferencia entre toda la memoria disponible y el tamaño del kernel. Un
kernel muy pequeño deja mucha memoria libre. Un kernel excesivamente grande puede
producir un trashing constante del sistema. (Un kernel muy grande puede llegar a los
2Mb en /LQX[, mientras que un kernel pequeño puede tener menos de 640k). Mas
adelante nos extenderemos en detallar en qué consiste un manejador que se carga
dinámicamente,.
El manejador objeto de esta practica es un manejador de tipo carácter para una
tarjeta de comunicaciones síncrona basada en el chip Serial &RPPXQLFDWLRQV&RQWUROOHU
6&& de Zilog para comunicaciones síncronas y asíncronas. Aunque puede ser
configurado en modo asíncrono, el manejador está especialmente diseñado para
comunicaciones síncronas de tramas 6'/& +'/&. El manejador está basado en un
manejador que obtuve vía Internet para comunicación $; para una tarjeta similar,
aunque ha sido modificado por completo y ampliado. En este sentido, puede decirse que
la labor realizada ha sido una labor de ingeniería inversa, de averiguar cómo funciona un
manejador existente para, a partir de ahí, ampliarlo y adaptarlo a mis necesidades
específicas. Agradezco a Joerg Reuter (dl1bke@db0pra.ampr.org) el haber puesto este
software a disposición de la comunidad internacional.
/$6&&'(=,/2*
A diferencia de la 8$57 , que es la utilizada en los ordenadores
personales compatibles para las comunicaciones serie, la serie =LORJ permite las
comunicaciones síncronas además de asíncronas. Esto le hace particularmente útil para
comunicaciones síncronas de tipo 6'/&+'/&/$3%;, con interfaces de tipo
56 y/o 56. El dispositivo permite la generación automática e inserción del
CRC en emisión, el cálculo del CRC en recepción, trabajar con reloj externo ó interno
de forma independiente tanto en emisión como recepción, inserción automática de ceros
en comunicaciones síncronas, trabajar en modo NRZ/NRZI y, en general, configurarse
en casi todos los modos posibles de comunicaciones síncronas conocidos. Esto unido a
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
sus capacidades para comunicaciones asíncronas, lo hace ideal para comunicaciones
serie hasta 19200bps. El modelo es compatible con la USART 8251 de Intel.
Aunque no es el caso de esta practica, este dispositivo puede trabajar en modo
DMA, transfiriendo ó recibiendo bloques de información directamente de/a memoria.
Sin utilizar las capacidades de DMA, el chip entrega una interrupción al sistema
por cada byte transmitido ó recibido. Esto hace que trabajar a más de 19200bps pueda
perjudicar al sistema por una sobrecarga de interrupciones (piénsese que, por ejemplo, a
19200 bps se recibe una interrupción cada 416 microsegundos, 208 microsegundos de
media en )XOOG~SOH[). Esto es un factor crítico a la hora de recibir o transmitir datos
puesto que si el sistema no es capaz de procesar interrupciones a esta velocidad, la
86$57 guarda los caracteres recibidos en un buffer interno de pocos caracteres
(antiguamente eran sólo 3, en versiones posteriores se han ampliado a 10). El buffer
interno se va vaciando conforme el sistema lee los caracteres recibidos en interrupciones
sucesivas. Si en la 86$57 se llena el buffer de recepción por no haber podido procesar
el sistema las interrupciones a suficiente velocidad, se produce un error de RYHUUXQ: la
86$57 nos informa de la pérdida de uno ó mas caracteres en recepción. De forma
idéntica, en transmisión, la 86$57 genera una interrupción cada vez que dispone de un
buffer libre para transmisión de un carácter. Si expira el tiempo de transferencia de un
carácter y no hay caracteres para transmitir, se produce un error de underrun: la 86$57
nos informa de que, debido a que no ha podido enviar caracteres lo suficientemente
rápido, la trama a enviar no ha podido ser transmitida. Estos dos errores (overrun en
recepción y XQGHUUXQ en transmisión) son típicos en las comunicaciones síncronas.
Cuando la velocidad de proceso es inferior a la de transmisión/recepción de datos.
Aunque la velocidad de proceso de las &38s actuales se ha multiplicado por
cuatro en los ultimos cinco años, el problema anterior se manifiesta con velocidades
superiores a 19200 bps y varios canales trabajando simultáneamente, lo que hace poco
aconsejable el utilizar este manejador para más de 19200 bps. No obstante, las líneas
para las que fue diseñado no precisan de una velocidad superior a 19200 bps, por lo que
esta no puede considerarse una restricción preocupante. Sin embargo, dejo abierta la
posibilidad de que alguien modifique el manejador para que utilice DMA, lo que
permitiría en el futuro velocidades muy superiores.
La 86$57 es un dispositivo de comunicaciones serie programable mediante
registros. Los registros se subdividen en 3 registros de lectura y 15 registros de escritura.
Para leer o escribir un registro se realiza una operación binaria: primero se selecciona el
registro y luego se lee o se escribe en él. El tiempo que media entre la selección del
registro y la lectura ó escritura es también un factor crítico: si se excede un tiempo dado
ó se realiza antes de tiempo la segunda operación la selección del registro queda
anulada, y el resultado es generalmente una lectura ó escritura sobre el registro 0, que
puede desprogramar por completo la 86$57. Este es un inconveniente añadido puesto
que el mismo código puede funcionar o no dependiendo de la velocidad del procesador.
/LQX[ facilita la independencia del procesador con una rutina del kernel, XGHOD\que
permite retardar en microsegundos la ejecución del código. Una de las labores del kernel
al arrancar es detectar la velocidad del procesador. De este modo, la rutina XGHOD\ nos
da un retardo en microsegundos independientemente del procesador en que nos
encontremos. Esta es una utilidad de /LQX[ que facilita enormemente al programador el
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
desarrollo de manejadores, pues permite disponer de una gran precisión en el tiempo a
la hora de mandar comandos a un dispositivo.
Como dijimos anteriormente, gran parte de la dificultad de un manejador reside en el
conocimiento de como funcionan las librerías de rutinas del kernel. Estas representan el
modo de interaccionar con el sistema operativo, de modo que sin ellas el manejador
seria inviable.
En el siguiente capítulo, comentaremos en qué consiste un módulo que se cargue
dinámicamente en el kernel, y cómo se consigue hacer esto en Linux. Despues
comentaremos la forma en que el manejador se inserta en el kernel, para pasar después a
comentar cada uno de los puntos de entrada (llamadas al sistema) que puede realizar el
manejador.
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
/2602'8/26',1$0,&26
En UNIX, existen dos formas diferentes de implementar un manejador: de tipo
modulo o como parte del sistema operativo. El diseño del kernel de /LQX[ es similar al
de los sistemas UNIX clásicos: arquitectura monolítica con sistemas de ficheros,
manejadores y un conjunto de elementos software que estan enlazados estáticamente en
el propio kernel para que los utilice en el arranque. El uso de módulos que se cargan
dinámicamente permite escribir partes del kernel como objetos independientes.
Comentare a continuación los detalles relativos a la instalación de un módulo en el
kernel
9LVLyQ*HQHUDO
Un modulo del kernel es sencillamente un fichero objeto que contiene las rutinas
y/o datos a cargar en el kernel que se está ejecutando. Cuando se carga, el código del
modulo reside en el espacio de memoria del kernel y se ejecuta íntegramente en su
contexto. Técnicamente, un modulo puede ser considerado como un conjunto de rutinas
cualesquiera, con la única excepción de que existen dos rutinas de nombre obligado:
LQLWBPRGXOH y FOHDQXSBPRGXOH Obviamente, estas son ejecutadas al cargar y
descargar el modulo del kernel respectivamente, y por lo demás, el programador que
realice un modulo debe tener en cuenta todas las restricciones asociadas a la generación
de manejadores.
El cargar un modulo en el kernel supone 4 tareas principales:
1.- Preparar el modulo para el espacio de la memoria. Leer el fichero objeto del
disco y resolver todos los símbolos externos. Un modulo sólo puede acceder a aquellos
módulos ya existentes en el kernel. Este paso lo realiza una parte del kernel llamada
‘UXQWLPH module ORDGHU’.
2.- Reservar memoria en el espacio de memoria del kernel para el nuevo módulo,
tanto para código como para datos, así como para información adicional del módulo.
3.- Copiar el código del módulo en su nueva dirección y proveer al kernel de
toda aquella información relevante para mantener el module (como la nueva tabla de
símbolos).
4.- Ejecutar LQLWBPRGXOH ya formando parte del kernel, del modulo en
cuestión.
(OFDUJDGRUGHPyGXORV
El cargador de módulos de /LQX[, LQVPRG es responsable de leer un objeto,
obtener su lista de símbolos, resolver todas las referencias del modulo, y enviar ese
modulo al kernel para su ejecución. El código fuente relativo al mismo, así como del
kernel de /LQX[ por completo,. está disponible en Internet. El formato en sistemas de
/LQX[ es el típico de ficheros ‘a.out’, aunque más recientemente se están implementando
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
soporte para ficheros de tipo ELF, y las ultimas versiones de los módulos las soportan.
Los ficheros de tipo a.out se almacenan como una cabecera, seguida de segmentos de
código y de datos, información relativa a la carga dinámica, la tabla de símbolos, y la
tabla de cadenas de caracteres. Todas estas partes son leídas por insmod para su uso
posterior:
La tabla de símbolos se almacena en el fichero objeto como un array de
estructuras de tipo VWUXFWQOLVW. Los nombres de los símbolos se encuentran en la tabla
de cadenas, inmediatamente después de la tabla de símbolos del fichero. Cada entrada a
la tabla de símbolos contiene el desplazamiento del nombre asociado dentro de la
estructura (tipo n_un.n_strx).
2.- Se lee la tabla de símbolos. Dentro de LQVPRG, cada símbolo es leído e insertado en
un árbol binario para que la búsqueda de símbolos sea más eficiente. Las direcciones de
los símbolos BLQLWBPRGXOH y BFOHDQXSBPRGXOH, la funciones de inicialización y de
borrado se salvan para su uso posterior.
3.- Resolución de todas las referencias externas. LQVPRG obtiene la lista de símbolos del
kernel utilizando la llamada JHWBNHUQHOBV\PV, la cual devuelve un array de estructuras
de tipo VWUXFWNHUQHOBV\P, cada una de cuyas entradas contiene el nombre y la dirección
en el kernel de un símbolo.
Una vez que se han resuelto los símbolos, LQVPRG busca en el árbol generado a
partir de la tabla de referencias externas, actualizando el campo QBYDOXH de cada
estructura de tipo QOLVW con el valor de la dirección de dicha variable, que es ya una
dirección del kernel. Si no se obtiene la dirección de todas las variables externas
referenciadas, se emite un mensaje de error, y se sale sin insertar el módulo.
4.- Se reajustan las direcciones del kernel actualizando las direcciones reales en el
kernel de las variables referenciadas, tanto en la zona de código como en la de datos. Se
utiliza una estructura de tipo UHORFDWLRQBLQIR. Una vez hecho esto, todas las referencias
externas del módulo apuntan a las direcciones del kernel apropiadas.
5.- Se reserva espacio de memoria para el módulo mediante una llamada a
FUHDWHBPRGXOH Como argumentos para FUHDWHBPRGXOH tenemos el nombre del modulo
y su tamaño total.
6.- Se carga el modulo en la memoria del kernel mediante una llamada a LQLWBPRGXOH .
Esta llamada tiene varios argumentos, y LQVPRG debe de construir las estructuras de
datos antes de hacer la llamada. Parámetros para esta llamada son el nombre del
modulo, los nombres de los segmentos de texto y de datos, el tamaño del código en
bytes, y punteros a estructuras en las cuales hay punteros a las funciones init_module y
FOHDQXSBPRGXOH, así como una estructura que indica cual son los símbolos del módulo y
sus variables y cuales son externos. Según se resuelven las referencias a los símbolos del
kernel, se actualizan las tablas del kernel para que contengan los símbolos del nuevo
módulo.
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
Obsérvese que no hay que confundir la llamada a LQLWBPRGXOH (escrita por el
programador del manejador) con la llamada del sistema LQLWBPRGXOH, que forma parte
del kernel del sistema, y sirve para insertar un módulo cualquiera.
,16(5&,Ï1'(6,167$/$&,21'(/.(51(/
Como
ya hemos comentado anteriormente, el manejador se carga
dinámicamente, lo que quiere decir que no forma parte del sistema operativo
inicialmente, sino que, una vez arranca el sistema operativo, mediante una serie de
instrucciones se realiza la carga del manejador. Esto permite mucha mayor flexibilidad a
la hora de desarrollarlo pues no es necesario compilarlo junto con el resto del sistema
operativo cada vez que se genera una nueva versión.
Como ya dijimos anteriormente, /LQX[ dispone de la instrucción LQVPRG para
cargar un módulo dinámicamente en el sistema operativo. Se facilita enormemente la
tarea al programador, que sencillamente tiene que compilar con unos SUDJPDV
determinados. Después de realizar las tareas anteriormente descritas, insmod llama
automáticamente a una rutina dentro del código del manejador que se encarga de
realizar la inicialización del manejador (LQLWBPRGXOH).
¿Que es lo que se ha de hacer durante la inicialización del módulo?.
Básicamente, reservar memoria para las estructuras de datos, detectar la presencia o no
de los chips de comunicaciones para evitar fallos en caso de que no estén en el sistema,
ajustar los vectores de interrupción de todas las 86$57s asociadas, e inicializar las
estructuras de datos del manejador. Esto es lo que se hace en la rutina de nombre
LQLWBPRGXOH (el nombre esta forzado por el sistema de modo que todo manejador que se
cargue dinámicamente debe de tener una rutina con ese nombre).
La rutina init_module solo utiliza unas pocas variables locales para
inicialización. La primera parte es la siguiente:
LQWLQLWBPRGXOHYRLG
^
LQWFKLSFKDQASDUDLQGH[DUQXPHURGHFKLS\GHFDQDO
UHJLVWHULRBSRUWFWUO3DUDDFFHGHUDORVSXHUWRVGHFRQWUROGHODV86$57
ORQJIODJVGHOD&38
/* Se inicializan algunas estructuras de datos necesarias para el manejador.: */
PHPVHWVFFBGULYHUVL]HRIVWUXFWWW\BGULYHU
VFFBGULYHUPDJLF 77<B'5,9(5B0$*,&PDJLFRGHOVLVWHPD
VFFBGULYHUQDPH VFF
VFFBGULYHUPDMRU =B0$-259HUVLyQ
VFFBGULYHUPLQRUBVWDUW 'LVSRVLWLYRPHQRU
VFFBGULYHUQXP 1FKLSV1XPHURGHFDQDOHV
VFFBGULYHUW\SH 77<B'5,9(5B7<3(B6(5,$/7LSRGHGHYLFH
VFFBGULYHUVXEW\SH 1RHVQHFHVDULR
VFFBGULYHULQLWBWHUPLRV WW\BVWGBWHUPLRV
VFFBGULYHULQLWBWHUPLRVFBFIODJ % _&6_&5($'_+83&/_&/2&$/
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
VFFBGULYHUIODJV 77<B'5,9(5B5($/B5$:
VFFBGULYHUUHIFRXQW VFFBUHIFRXQW
VFFBGULYHUWDEOH VFFBWDEOH
VFFBGULYHUWHUPLRV VWUXFWWHUPLRVVFFBWHUPLRV
VFFBGULYHUWHUPLRVBORFNHG VWUXFWWHUPLRVVFFBWHUPLRVBORFNHG
Seguidamente, se ajustan los punteros a funciones del manejador, que serán los
puntos de entrada para las distintas llamadas propias de un manejador de tipo carácter:
VFFBGULYHURSHQ VFFBRSHQ
VFFBGULYHUFORVH VFFBFORVH
VFFBGULYHUZULWH VFFBZULWH
VFFBGULYHUVWDUW VFFBVWDUW
VFFBGULYHUVWRS VFFBVWRS
VFFBGULYHUSXWBFKDU VFFBSXWBFKDU;
VFFBGULYHUIOXVKBFKDUV VFFBIOXVKBFKDUV
VFFBGULYHUZULWHBURRP VFFBZULWHBURRP
VFFBGULYHUFKDUVBLQBEXIIHU VFFBFKDUVBLQBEXIIHU
VFFBGULYHUIOXVKBEXIIHU VFFBIOXVKBEXIIHU
VFFBGULYHUWKURWWOH VFFBWKURWWOH
VFFBGULYHUXQWKURWWOH VFFBXQWKURWWOH
VFFBGULYHULRFWO VFFBLRFWO
VFFBGULYHUVHWBWHUPLRV VFFBVHWBWHUPLRV
Se registra el manejador como de tipo terminal en el kernel :
LIWW\BUHJLVWHUBGULYHUVFFBGULYHU
SDQLF&RXOGQ
WUHJLVWHU=6&&GULYHU?Q
La rutina printk es el equivalente a printf para los manejadores. Funciona de
modo diferente, pues es mas rápida para evitar bloqueos y además la salida por defecto
se produce en el fichero de log del sistema (/vad/adm/messages). Pese a todo ello, debe
de usarse con cautela en interrupciones críticas, pues consume bastante tiempo.
SULQWN%$11(5
SULQWN%$11(5
SULQWN%$11(5
Esta sentencia evita el que se pueda acceder a zonas de memoria no válidas en
caso de que Nchips tenga una valor superior al del máximo numero de chips
contemplados.
LI1FKLSV!0$;6&&1FKLSV 0$;6&&
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
El código que viene a continuación realiza la inicialización de las estructuras de
datos de las UART, y además comprueba que los chips están instalados, es decir, realiza
la autodetección de los dispositivos. La rutina FKHFNBUHJLRQ solicita al sistema
operativo el acceso al puerto cuya dirección es la que se le indica como argumento. Una
vez detectada la existencia del chip, mediante UHTXHVWBUHJLRQ se solicita esas
direcciones de I/O como direcciones propias de este manejador. Finalmente, se informa
al usuario de los resultados de la búsqueda, así como de los canales disponibles. Cada
86$57 dispone de dos canales, de modo que por cada chip detectado el usuario
dispondrá de dos canales, a los que accederá como ficheros del directorio /dev. Las
direcciones base e IRQs utilizadas por cada chip están predeterminadas ( Base 01b0 e
IRQ 5 para el primer chip y base 01b4 y e IRQ 7 para el segundo). De este modo, al
terminar la inicialización el usuario dispone de los siguientes canales:
/dev/scc0 como canal A del primer chip.
/dev/scc1 como canal B del primer chip.
/dev/scc2 como canal A del segundo chip.
/dev/scc3 como canal B del segundo chip.
Y de ahí en adelante...
El vector de interrupción no se ha activado aun por motivos de seguridad del
sistema, eso se hará mas adelante, cuando mediante una llamada especifica se inicialize
el manejador.
,QLFLDOL]DWRGRVORVFKLSVGHOVLVWHPD
IRUFKLS FKLS1FKLSVFKLS
^
PHPVHWFKDU6&&B,QIR>FKLS@VL]HRIVWUXFWVFFBFKDQQHO
PHPVHWFKDU6&&B,QIR>FKLS@VL]HRIVWUXFWVFFBFKDQQHO
FWUO 6&&BFWUO>FKLS@
LIFWUO
FRQWLQXH
'DGRTXHODVRSHUDFLRQHVGH(6FRQHOSXHUWRVHKDFHQHQGRVIDVHVKD\TXH
LQKLELULQWHUUXSFLRQHV
VDYHBIODJVIODJVFOL
FKHFNBUHJLRQFWUO
2XWEFWUO
2XW5HJFWUO5[
&RPSUREDFLyQGHTXHHOFKLSHVWiHQHOVLVWHPD
LI,Q5HJFWUO5 [
^
UHVWRUHBIODJVIODJV
FRQWLQXH
`
6&&B,QIR>FKLS@PDJLF 6&&B0$*,&
6&&B,QIR>FKLS@FWUO 6&&BFWUO>FKLS@
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
6&&B,QIR>FKLS@GDWD 6&&BGDWD>FKLS@
6&&B,QIR>FKLS@HQKDQFHG 6&&B(QKDQFHG>FKLS@
6&&B,QIR>FKLS@QXPEHU FKLS
6&&B,QIR>FKLS@PDJLF 6&&B0$*,&
6&&B,QIR>FKLS@FWUO 6&&BFWUO>FKLS@
6&&B,QIR>FKLS@GDWD 6&&BGDWD>FKLS@
6&&B,QIR>FKLS@HQKDQFHG 6&&B(QKDQFHG>FKLS@
6&&B,QIR>FKLS@QXPEHU FKLS
UHVWRUHBIODJVIODJV
`
SULQWN,QLW=GULYHUXFKDQQHOVXVLQJXLUTV?Q1FKLSV,YHF1
IRUFKDQ FKDQ1FKLSVFKDQ
^
SULQWNGHYVLGDWDSRUW [[FRQWUROSRUW [[V?Q
VFFBGULYHUQDPHFKDQ6&&BGDWD>FKDQ@6&&BFWUO>FKDQ@
6&&B,QIR>FKDQ@FWUO"IRXQGPLVVLQJ
LI6&&B,QIR>FKDQ@FWUO ^
6&&BFWUO>FKDQ@ `HOVH^
UHTXHVWBUHJLRQ6&&BFWUO>FKDQ@VFFFWUO
UHTXHVWBUHJLRQ6&&BGDWD>FKDQ@VFFGDWD
`
`
UHWXUQ
`
Este es el código que se ejecuta cada vez que se realiza una inserción del
modulo, si bien no es suficiente para que se active el manejador. Para realizar esto, será
preciso una llamada adicional del programa usuario (una llamada LRFWO con parámetro
SCC_INIT) que activa la rutina siguiente:
VWDWLFYRLG
]BLQLWYRLG
^
VWUXFWVFFBFKDQQHO
VWUXFWVFFBFKDQQHO
LQW
XQVLJQHGORQJ
LQW
LQW
LQW
3DJ
VFF3XQWHURDFDQDO$GHOD6&&
VFFE,GHPFDQDO%
FKLSGHFKLSTXHHVWDPRVHGLWDQGR
IODJVGHOD&38
UHVXOW5HVXOWDGRGHODXOWLPDRSHUDFLRQ
VFFLUT,QWHUUXSFLyQGHOD6&&SHGLGD
L
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
En primer lugar, la rutina fuerza un RESET de todos los chips presentes en el
sistema. Esto en la 86$57 se realiza escribiendo en el registro 9 del canal A un valor
predeterminado (FHWRES). Se utilizan punteros a funciones para cada tipo de
interrupción (TXBE,EXST,RXXS,SPRX), que inicialmente apuntan a una función nula.
Posteriormente, cuando el usuario defina el protocolo a soportar por ese canal, se
cambiaran dichos punteros a las funciones C apropiadas según el protocolo. Esto le da
mayor flexibilidad al manejador, permitiendo soportar distintos protocolos con el mismo
código. El salvar los IODJV e inhibir las interrupciones se debe a que las operaciones de
lectura y escritura son binarias, como ya se ha comentado. En el registro 2 se escribe un
vector que posteriormente nos indicara de a que canal y a cual chip ha llegado una
interrupción.
IRUFKLS FKLS1FKLSVFKLS
^
VFF 6&&B,QIR>FKLS@
VFF!IXQF>@IQ VFF!IXQF>@IQ VFF!IXQF>@IQ VFF!IXQF>@IQ QRLQW
VFFE VFF
VFFE!IXQF>@IQ VFFE!IXQF>@IQ VFFE!IXQF>@IQ VFFE!IXQF>@IQ
QRLQW
LIVFF!FWUO
FRQWLQXH
VDYHBIODJVIODJVFOL
,QLFLDOL]DFLyQGHOFKLSSURSLDPHQWHGLFKR
2XWEVFF!FWUO
2XW5HJVFF!FWUO5)+:5(6
)XHU]DHOUHVHW+DUGZDUH
XGHOD\/
'DOHXQSRFRGHWLHPSRPDVGHOUHTXHULGR
ZUVFF5FKLS
9HFWRUGH,QWHUUXSFLyQ
ZUVFF59,6
(OYHFWRULQFOX\HHVWDGR
UHVWRUHBIODJVIODJV
`
+DELOLWDGHQXHYRODVLQWHUUXSFLRQHV
IRUL L,YHF1L
^
VFFLUT ,YHF>L@
LIVFFLUT VFFLUT 3DUWLFXODULGDGHVGHOGLVHxRGHO3&GHVGHHO,%0$7
UHVXOW UHTXHVWBLUTVFFLUTVFFBLVU6$B,17(55837'5,9(56&&
`
6&&ORJ5HVXOWDGRGHUHTXHVWBLUT GUHVXOW
'ULYHUB,QLWLDOL]HG `
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
La rutina UHTXHVWBLUTdel kernel nos permite solicitar un vector de interrupción
para su uso por el manejador. En la arquitectura del IBM PC, las interrupciones 3 y 4 se
utilizan en /LQX[ para las líneas de comunicaciones serie (el equivalente al COM1 y
COM2 del MS-DOS), por lo que utilizarlas sería eliminar la posibilidad de usar por
ejemplo el ratón y otras capacidades de comunicaciones. La IRQ 2 está multiplexada en
cascada de modo que no interesa utilizarla. La IRQ 6 se utiliza para la disquetera. La
IRQ 5 en principio queda libre, así como la IRQ 7 que es utilizada por el manejador de
impresora, pero dicho manejador puede funcionar en modo poll, en el que no es preciso
trabajar mediante interrupciones. Por tanto, utilizo las IRQ 5 y 7 permitiendo el uso de 2
USART, o, lo que es lo mismo, 4 canales de comunicaciones.
Una vez instalado el manejador con LQVPRG, y realizada la llamada LRFWO con
SCC_INIT, el manejador está inicializado y listo para su utilización posterior. El
proceso de instalación del manejador en el kernel queda completado. Realizar el paso
inverso, esto es desinstalarlo del kernel, puede ser realizado mediante la ejecución de
UPPRG que es el descargador de módulos. Esto, aparte de facilitar enormemente el
desarrollo (se puede instalar y desinstalar una versión en cuestión de segundos), permite
reajustar el kernel según nuestras necesidades y es naturalmente mucho más elegante.
Veamos en detalle la función que elimina el modulo del kernel:
YRLGFOHDQXSBPRGXOHYRLG
^
ORQJIODJV
LQWVFFLUT
XQVLJQHGFKDQ
LQWL
Lo primero que hace la función correspondiente es determinar si el modulo está
actualmente en uso o no por algún proceso. Si es así será imposible descargarlo de la
memoria, debiendo esperar a que el proceso dueño canal haga una llamada a FORVH (el
sistema lo haría automáticamente caso de que el proceso muriese). En caso contrario, se
elimina de la lista de WW\V el GHYLFH de tipo SCC, se liberan (mediante UHOHDVHBUHJLRQ y
IUHHBLUT) las direcciones base e IRQs de los chips correspondientes, y se desactivan los
temporizadores asociados al manejador de la SCC. Estos temporizadores son comunes a
todo el kernel, y se utilizan para obtener una base de tiempos de una precisión de en
torno a los 30 milisegundos, sin que ello conlleve una sobrecarga del sistema.
LI02'B,1B86(
SULQWN0RGXORDFWXDOPHQWHHQXVRLPSRVLEOHGHVFDUJDU?Q
HOVH
^
LIWW\BXQUHJLVWHUBGULYHUVFFBGULYHU
SDQLF&RXOGQ
WXQUHJLVWHU=6&&GULYHU?Q
SULQWN8QORDGLQJ=GULYHUXFKDQQHOVXVLQJXLUTV?Q1FKLSV,YHF1
VDYHBIODJVIODJVFOL
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
IRUFKDQ FKDQ1FKLSVFKDQ
^
SULQWNGHYVLGDWDSRUW [[FRQWUROSRUW [[V?Q
VFFBGULYHUQDPHFKDQ6&&BGDWD>FKDQ@6&&BFWUO>FKDQ@
6&&B,QIR>FKDQ@FWUO"IRXQGPLVVLQJ
LI6&&B,QIR>FKDQ@FWUO ^
UHOHDVHBUHJLRQ6&&BFWUO>FKDQ@
UHOHDVHBUHJLRQ6&&BGDWD>FKDQ@
`
`
LI'ULYHUB,QLWLDOL]HG
^
IRUL L,YHF1L
^
VFFLUT ,YHF>L@
LIVFFLUT
VFFLUT 3RUHOGLVHxRGHO,%0B3&
IUHHBLUTVFFLUT
`
WLPHUBWDEOH>6&&B7,0(5@IQ WLPHUBWDEOH>6&&B7,0(5@H[SLUHV WLPHUBDFWLYH a6&&B7,0(5
`
UHVWRUHBIODJVIODJV
`
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
86$1'2(/0$1(-$'25
Hemos visto como se instala en el kernel el manejador. Pero no debemos perder
de vista que el manejador no es sino un servidor diseñado para que otros programas lo
utilicen y realicen comunicaciones serie pudiendo desentenderse del manejo del
dispositivo ( en este caso, de las USART de comunicaciones). Para ello, el programa
que utilice el manejador deberá seguir un determinado protocolo. Dicho protocolo se
traduce en una serie de llamadas estándar de 81,; (RSHQFORVHZULWHUHDGLRFWO) que
el propio sistema operativo se encargará de progresar hacia el manejador. Es durante el
proceso de carga del modulo cuando el manejador indica al sistema operativo cual es la
correspondencia entre las llamadas 81,; y sus rutinas para tratar dichas llamadas, lo
que llamábamos SXQWRVGHHQWUDGD .
Anteriormente comentábamos que la visión desde el punto de vista de un
proceso del manejador, siguiendo la filosofía del 81,;, era la de un fichero. Que se
adoptaba el nombre /dev/sccX, con X=0,1,2,3 según el canal que se estuviese utilizando,
para que el usuario indicase el canal por el que comunicar.
Quiere esto decir que para empezar a trabajar con un canal, el programa usuario
que utilice el manejador debe de realizar una llamada RSHQ de 81,; con el nombre de
uno de estos ficheros según el canal que desee utilizar. Así, si se desea usar el canal A
de la primera SCC, el programa usuario realizaría una llamada RSHQ³GHYVFF´
PRGR Esta llamada devuelve un identificador de canal, que es el que se utiliza en
subsiguientes llamadas al dispositivo (ZULWHUHDGLRFWO). Finalmente, una llamada a
FORVH indicaría al sistema que no se desea trabajar mas con él.
Veamos la rutina VFFBRSHQ, que se activa al realizar la llamada RSHQcon el
nombre del fichero de un canal. Para aclarar un poco las cosas, diremos que esta es la
zona de código que se activa en el manejador cuando el programa usuario (cualquier
proceso que utiliza esta linea) hace una llamada a open con /dev/sccx como argumento.:
LQWVFFBRSHQVWUXFWWW\BVWUXFWWW\VWUXFWILOHILOS
^
VWUXFWVFFBFKDQQHOVFF
LQWFKDQ
LQWIODJV
Lo primero que hace la rutina es comprobar que los parámetros que se le pasan
son correctos. Esto es muy crítico pues como decíamos anteriormente, una caída del
manejador normalmente implica una caída general del sistema. En caso de error de
algun parámetro, se devuelve el tipo de error y se termina la llamada
LIWW\
UHWXUQ(12'(9
FKDQ 0,125WW\!GHYLFHWW\!GULYHUPLQRUBVWDUW
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
LIFKDQ__FKDQ! 1FKLSV
UHWXUQ(12'(9
VFF 6&&B,QIR>FKDQ@
WW\!GULYHUBGDWD VFF
WW\!WHUPLRV!FBFIODJ a&%$8'
La llamada realiza en primer lugar una serie de comprobaciones de los
argumentos recibidos para que no se produzcan más adelante errores fatales
(recordemos que si se produjese un error de accesos a memoria, etc... dentro del código
del manejador se produciría una caída general de todo el sistema). Para el canal pedido,
se comprueba que está disponible (esto significa que el algoritmo de detección en el
arranque identificó que el sistema disponía del chip asociado a dicho canal), se
incrementa el contador que indica que está siendo usado, y se devuelve que no hay error
en el caso de que todo sea correcto.
LIVFF!WW\ 18//
^
VFF!WW\BRSHQHG
SULQWNVFFBRSHQ'ULYHUEXV\
UHWXUQ(%86<
`
LIGHI02'8/(
RSHQV
SULQWNVFFBRSHQRSHQV GRSHQV
02'B,1&B86(B&2817
HQGLI
LI'ULYHUB,QLWLDOL]HG
^
SULQWNVFFBRSHQ'ULYHUQRWLQLWLDOL]HG
UHWXUQ
`
LIVFF!PDJLF 6&&B0$*,&
^
SULQWN(5525VFFBRSHQEDGPDJLFQXPEHUIRUGHYLFHGG0$-25WW\
!GHYLFH0,125WW\!GHYLFH
UHWXUQ(12'(9
`
VFF!WW\ WW\
UHVHWBP\ORJVFF
VFF!IUDPHBVL]H %8)6,=(
VDYHBIODJVIODJVFOL
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
WLPHUBWDEOH>6&&B7,0(5@IQ VFFBWLPHU
WLPHUBWDEOH>6&&B7,0(5@H[SLUHV QRZ
WLPHUBDFWLYH_ 6&&B7,0(5
UHVWRUHBIODJVIODJV
UHWXUQ
`
Las tablas de temporizadores pertenecen al kernel del sistema, concretamente a
la parte del kernel encargada de manejo de los terminales. El manejador utiliza estas
tablas para generar temporizadores de múltiplos de 30 ms de una forma elegante, sin
interceptar la interrupción de reloj, y evitando una sobrecarga del sistema.
A partir de este punto el usuario debe de programar la línea con alguno de los
protocolos disponibles: Esto se realiza mediante una llamada VFFBLRFWO con los
parámetros correspondientes a 6&&B63527 En el código original, el protocolo se
fijaba elemento por elemento, hasta quedar definitivamente configurado. Era mejor para
el tipo de aplicaciones que se iban a fijar por nosotros el utilizar unas tablas de
inicialización de registros, que definiesen de forma fija los diferentes parámetros a
utilizar, y dejar abierta la posibilidad de modificar unos pocos parámetros (como la
velocidad), dinámicamente, una vez programada la línea.
La llamada LRFWO se utiliza también para poder enviar o recibir tramas del
sistema. ¿Por qué utilizar esta llamada en lugar de las tradicionalesUHDG o ZULWH para
lectura ó escritura?. La razón es un tanto singular.
Siendo un manejador de PRGRFDUiFWHU el modo en que se procesan las lecturas
y escrituras es carácter a carácter, no por tramas completas. Esto, que es muy frecuente
en síncrono, no lo es tanto en asíncrono, donde la estructura de la trama está definida
por la llegada de los IODJV de inicio y de fin, y el propio hardware dispone de elementos
que se encargan de la detección automática de principio/fin de trama, inserción
automática de ceros, y cálculo del CRC. En las comunicaciones síncronas las llamadas a
UHDG o ZULWH van asociadas a mensajes completos ó tramas. No ocurre así en las
comunicaciones asíncronas, en donde generalmente se reciben y envían los datos
carácter a carácter, y se determina por software el principio y el fin de trama, así como el
cálculo del CRC.
Por ser un manejador de modo carácter, las llamadas a ZULWH del proceso usuario
QRVHFRUUHVSRQGHQFRQXQD~QLFDOODPDGDDZULWHHQHOFyGLJRGHOPDQHMDGRU., esto
es, puede ocurrir que una llamada a write del proceso usuario en la que se solicite el
envío de 200 bytes se corresponda con varias llamadas a la rutina scc_write dentro del
código del manejador (por ejemplo llamadas sucesivas con 20,30,100 y 50 bytes,
totalizando los 200 solicitados por el proceso usuario). Para evitar esto, sería necesario
cambiar el manejador a un manejador de tipo bloque, lo cual no resultaba interesante
por otros motivos que se expondrán mas adelante. Problema: ¿ como determinar donde
empieza y donde acaba una trama que el proceso usuario ha solicitado enviar ?.
En el manejador original, se determinaba el principio/fin de trama mediante un
protocolo (NLVVHQFRGHUGHFRGHU) acordado entre proceso usuario y manejador. De esta
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
forma, al recibir una llamada a ZULWH, el manejador examinaba el contenido de los datos
que se quería enviar para determinar si era parte de una trama o bien una trama
completa. Si no constituía una trama, se almacenaba en memoria pero no se comenzaba
a transmitir físicamente. Igualmente, en recepción, al terminar de recibir una trama, se
codificaba en protocolo NLVV y se almacenaba en una zona de memoria. El proceso
usuario, realizando sucesivas llamadas a UHDG, decodificaba igualmente la trama recibida
en protocolo NLVV, y de este modo determinaba los principios y finales de tramas.
Este método me pareció francamente ineficiente puesto que forzaba la existencia
de codificadores/decodificadores en ambas partes (manejador y proceso usuario) para
solventar un problema de concepto.
Podría haber optado por desarrollar un manejador de tipo bloque, pero ello
hubiese impedido su utilización como manejador de carácter en determinados
protocolos asíncronos.
En 81,; existe una llamada,LRFWO, que se usa en general para fijar parámetros
del dispositivo que se está usando. Esta llamada es de propósito general, por lo que
admite varios argumentos, siendo un de ellos el tipo de llamada ioctl a realizar.
Así pues, decidí implementar llamadas especiales a LRFWOque son6&&B5($'y
6&&B:5,7(, de modo que estas llamadas se utilizasen especialmente para realizar HO
HQYtR \ OD OHFWXUD GH WUDPDV VLQFURQDV FRPSOHWDV Cada llamada a ioctl con
argumento 6&&B5($' y/o 6&&B:5,7( entregaba ó transmitía una trama, con lo
que era innecesario codificar/decodificar las tramas en protocolo NLVV. Las llamadas a
UHDG y ZULWH quedaban como llamadas para protocolos asíncronos, preservando así la
posibilidad de transferir en asíncrono byte a byte. De este modo, tenemos
simultáneamente capacidades de recepción y transmisión en modo bloque y/o en modo
carácter, lo cual es sumamente interesante dado el amplio espectro de protocolos con los
que necesitamos trabajar.
En el modo normal de funcionamiento en síncrono, pues, se utilizan sucesivas
llamadas a LRFWO( 6&&B:5,7( para transferir tramas y llamadas a LRFWO
6&&B5($'para recibir tramas. Cada llamada a ioctl se traduce en la recepción
/el envío de una trama completa (según sea6&&B5($' ó 6&&B:5,7(). La llamada
ioctl en este manejador tiene, además de estas dos funciones, las siguientes:
6&&B63((':
6&&B,1,7:
6&&B567$7
6&&B:5,7(
6&&B5($'
6&&B/2*
6&&B06,=(
transferir por la línea
Cambio de la velocidad de la línea.
Inicialización general del manejador,
Obtención de estadísticas de un canal.
Envío de una trama
Recepción de una trama
Activación/desactivación del buffer de log.
Determina el tamaño máximo de trama que se puede
En lo sucesivo, veremos en detalle como funciona la llamada LRFWO, que es la
utilizada por el programa cliente para utilizar el manejador en síncrono (ignorando las
llamadas a ZULWH y UHDG por los motivos anteriormente expuestos).
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
$1$/,6,6'(/&2',*25(/$7,92$/$
//$0$'$,2&7/
VWDWLFLQW
VFFBLRFWOVWUXFWWW\BVWUXFWWW\VWUXFWILOHILOHXQVLJQHGLQWFPGXQVLJQHGORQJDUJ
^
VWUXFWVFFBFKDQQHOVFF WW\!GULYHUBGDWD
XQVLJQHGORQJU
XQVLJQHGLQWUHVXOW
XQVLJQHGLQWHUURU
XQVLJQHGLQWL
XQVLJQHGUHWU\V
La rutina se protege de fallos tales corrupción de la memoria mediante la
comprobación de que hay determinados valores en determinadas posiciones de
memoria. Esto evita problemas de caída del sistema:
LIVFF!PDJLF 6&&B0$*,&
^
SULQWN(5525VFFBLRFWOEDGPDJLFQXPEHUIRUGHYLFHGG
0$-25WW\!GHYLFH0,125WW\!GHYLFH
UHWXUQ(12'(9
`
U 12B68&+B3$5$0
Una primera función de LRFWO es la de inicialización del manejador. Si no se ha
realizado aún, cualquier otra llamada a LRFWO no tiene sentido:
LI'ULYHUB,QLWLDOL]HG
^
LIFPG 7,2&6&&,1,
^
LIVXVHU
UHWXUQ(3(50
]BLQLW
UHWXUQ
`
UHWXUQ(,19$/
`
3DJ
$UJXPHQWRQRYDOLGRSRUQRHVWDULQLFLDOL]DGRHOVLVWHPD
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
A continuación se tratan los comandos normales, LOGFLIP y RDLOG se usan
como mecanismo de depuración
VZLWFKFPG
^
FDVH6&&B/2*)/,3
VFF!ORJEXIORJJLQJ VFF!ORJEXIORJJLQJ"
EUHDN
FDVH6&&B5'/2*/HHHQEXIIHUGH/2*
^
HUURU YHULI\BDUHD9(5,)<B:5,7(YRLGDUJVL]HRI%8))(5B/2*
LIHUURU
UHWXUQHUURU
6&&ORJ&RSLRE\WHVGH/2*HQEXIIHU%XISRV G
VFF!ORJEXIEXISRV
PHPFS\BWRIVYRLGDUJVFF!ORJEXIVL]HRI%8))(5B/2*
UHWXUQ
EUHDN
`
SCC_WRITE es la función que realiza el envío de tramas por la línea. Existe un
puntero a función dentro del canal que le indica la función específica para cada
protocolo:
FDVH6&&B:5,7((VFULELUWUDPD
^
HUURU YHULI\BDUHD9(5,)<B5($'YRLGDUJVL]HRI)5$0(
LIHUURU
UHWXUQHUURU
PHPFS\BIURPIVRXUBIUDPHYRLGDUJVL]HRI)5$0(
/ODPDPRVDODIXQFLRQTXHHVFULEH
LIRXUBIUDPHFRQWURO
UHWU\V RXUBIUDPHFRQWURO
HOVH
UHWU\V LIVFF!ZULWHIFQ
^
UHVXOW VFF!ZULWHIFQVFFRXUBIUDPHUHWU\V
`
HOVH
^
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
UHVXOW ()$8/7
`
UHWXUQUHVXOW
EUHDN
`
6&&B63(('HVODOODPDGDSDUDHOFDPELRGHYHORFLGDGGHWUDQVPLVLyQUHFHSFLyQ
FDVH6&&B63(('
^
IRUL L0$;B63(('L
^
LIVSBGHIHFWR>L@ DUJ
^
VFF!PRGHPVSHHG DUJ
VHWBVSHHGVFF
UHWXUQ
`
`
UHWXUQ(,19$/
EUHDN
`
/* MSIZE fija el tamaño máximo de mensaje a recibir/enviar. */
FDVH6&&B06,=(
^
LIDUJ!%8)6,=(__DUJ
UHWXUQ(,19$/
HOVH
VFF!IUDPHBVL]H DUJ
UHWXUQ
EUHDN
`
/* SCC_READ es la función de lectura de trama. Es también dependiente del protocolo.
*/
FDVH6&&B5($'/HFWXUDGHWUDPD
^
6&&ORJ/HFWXUDGHWUDPD
/ODPDPRVDODIXQFLRQGHOHFWXUD
LIVFF!UHDGIFQ
^
UHVXOW VFF!UHDGIFQVFFRXUBIUDPH
`
HOVH
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
^
UHWXUQ()$8/7
`
PHPFS\BWRIVYRLGDUJRXUBIUDPHVL]HRI)5$0(
UHWXUQUHVXOW
EUHDN
`
SCC_START realiza la inicialización del canal, enviando los comandos de
inicialización a la USART. Estos comandos son diferentes según el protocolo que
hayamos fijado para dicho canal.
case SCC_START: /* Inicialización de canal */
{
SCClog(1,("inicialización del canal "));
reset_channel(scc);
return(0);
break;
}
case SCC_SPROT: /* Inicialización del protocolo */
{
if ( ( (int) arg<=MAX_PROTOCOL) && ( (int) arg>0) )
{
result = set_protocol( scc, (int) arg );
return(result);
}
else
return( -EINVAL );
break;
}
case SCC_RSTAT: /* lectura de estadísticas */
{
error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct scc_stat));
if (error)
return(error);
SCClog(2,(" Copio bytes de estadisticas en buffer.Bufpos = %d ",
scc->logbuf.bufpos));
memcpy_tofs( (void *) arg, &scc->stat, sizeof(struct scc_stat) );
return(0);
break;
}
/* SCC_RINDEX se usa para la lectura de estadísticas generales. */
case SCC_RINDEX: /* lectura de Datos varios del canal */
{
ZZZGDWVLILXSPHV
3DJ
Jorge OCÓN ALONSO
Tutor: Juan Zamorano <jzamora@fi.upm.es>
error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(INDEX));
if (error)
return(error);
SCClog(2,(" Copio estado INDEX en buffer"));
memcpy_tofs( (void *) arg, &scc->c_trama_env, sizeof(INDEX) );
return(0);
break;
}
SCC_RPROT permite leer el protocolo con el que está funcionando una línea.
FDVH6&&B53527OHFWXUDGHHVWDGtVWLFDV
^
LI'ULYHUB,QLWLDOL]HG
UHWXUQ()$8/7
HOVH
UHWXUQVFF!SURWRFRO
EUHDN
`
GHIDXOW
UHWXUQ(12,2&7/&0'
`
UHWXUQ
`
CONCLUSIONES
El manejador objeto de esta práctica está actualmente funcionando en sistemas
de tiempo real (equipos de FRQFHQWUDGRUHV GH HVWDFLyQ) en los trenes de Buenos
Aires.(TBA). Los FRQFHQWUDGRUHV GH HVWDFLyQ son equipos de comunicaciones
dedicados a la centralización de todos los equipos de estación. Al hablar de HTXLSRVGH
HVWDFLyQ nos referimos a lasH[SHQGHGRUDVDXWRPiWLFDVGHELOOHWHV que emiten billetes
sin intervención de un operador, las H[SHQGHGRUDV GH YHQWDQLOOD, que emiten billetes
con la ayuda de un operador y los PROLQHWHVGHSDVR que controlan el paso de viajeros,
comprobando la validez de su billete y anotando en su banda magnética el paso del
viajero si fuese necesario. Sin ser un equipo que interaccione con el viajero, la misión de
los concentradores es esencial, puesto que ellos son los que recogen los datos de paso de
viajeros por los molinetes y de ventas de billetes en las expendedoras de taquilla y
automáticas. El concentrador de estación monitoriza y controla todos estos equipos, de
forma permanente, almacenando sus averías y alarmas, cambiando su modo de
funcionamiento si fuera preciso, ajustando la hora de dichos equipos, etc...
3DJ
ZZZGDWVLILXSPHV
Manejador de tipo Módulo para la SCC-8530 en LINUX
Trabajo de doctorado
El FRQFHQWUDGRUGHHVWDFLyQ es un PC Pentium con /LQX[ que trabaja de forma
permanente en comunicación constante con los molinetes de paso de viajeros y las
máquinas automáticas de venta de billetes, sin asistencia de ningún tipo. Comunica
mediante líneas síncronas con dichos equipos (utilizando el manejador objeto de esta
práctica), y comunica vía Ethernet y TCP/IP con un equipo principal situado en el
Centro de Control de Retiro, desde el cual se puede monitorizar el estado de todas y
cada una de las estaciones.
En Junio del 97, se habían instalado 3 concentradores en la estación de ONCE,
con un total de 12 líneas síncronas. La robustez de /LQX[ queda de manifiesto si
examinamos el comportamiento de estos equipos, que sin asistencia de ningún tipo,
permanecen durante semanas realizando un gran número de tareas de forma
completamente automatizada. A modo de ejemplo, diremos que en uno de los
concentradores se habían procesado más de 3 millones de interrupciones de la USART
en solo 3 días. Esto sólo nos da una idea del grado de fiabilidad del sistema. En el
futuro, se instalarán mas de 97 concentradores de estación en todas las líneas, y se
podrán monitorizar desde el Centro de Control de forma remota.
El manejador no es sino sólo una pieza más de un conjunto muy extenso de
software que abarca desde VFULSWV de configuración del sistema, y programas C de la
aplicación, hasta el desarrollo de una distribución de /LQX[ propia que instala a la vez el
sistema operativo y nuestras aplicaciones. En este sentido, sólo la condición de /LQX[ de
software libre nos ha permitido poder modificar los propios discos de instalación del
sistema operativo para que simultáneamente se instalen junto con él nuestras
aplicaciones (llegamos a tener que modificar el propio kernel, con todos los mensajes en
castellano, modificamos los discos de ERRW y de URRW de instalación, etc... ).
Para el usuario del concentrador, la máquina es una caja negra. Una vez
instalado el sistema operativo (con nuestra propia distribución), la máquina arranca
automáticamente con un usuario creado durante la instalación nuestras aplicaciones. No
existen terminales virtuales, ni se pide ORJLQ y SDVVZRUG. El usuario del sistema no sabe
UNIX, ni sabe siquiera cual es el sistema operativo de la máquina. Una serie de menús
le permiten al operador monitorizar todos los equipos, examinar sus alarmas, enviar
ordenes a los equipos remotos para cambiar su modo de funcionamiento, y hacer un
mantenimiento del concentrador. Muchas de estas características serían impensables en
un sistema operativo comercial, sencillamente porque el fabricante no hubiese
suministrado la información precisa para realizarlo.
Durante todo el desarrollo, pudimos comprobar diariamente la robustez del
sistema, la facilidad de detección de errores y la cantidad de herramientas disponibles
para la depuración y como soporte nuestro ( el propio manejador objeto de esta práctica
no es sino una ampliación de otro disponible públicamente en Internet ). Todo ello
confirma la validez del software libre para sistemas de control de tiempo real, así como
la excelente labor realizada por los creadores de /LQX[, a quienes quiero expresar mi
más sincero agradecimiento.
ZZZGDWVLILXSPHV
3DJ
830'$76,
FACULTAD DE INFORMÁTICA
'HSDUWDPHQWRGH$UTXLWHFWXUD\7HFQRORJtDGH6LVWHPDV,QIRUPiWLFRV
8QLYHUVLGDG3ROLWpFQLFDGH0DGULG
Campus de Montegancedo
Boadilla del Monte
28660 Madrid
ESPAÑA
Telf: +34 91 336-7399
Fax: +34 91 336-7412
http://www.fi.upm.es
ZZZXSPHV
Descargar