Procesos
Transcripción
Procesos
Sistemas Operativos 2 Procesos ➢ Índice ➢ ➢ Introducción de procesos en MINIX ➢ Estructura interna ➢ Gestión de procesos ➢ Comunicación entre procesos ➢ Planificación de procesos Implementación de procesos en MINIX ➢ Instalación y utilización ➢ Organización del código en MINIX ➢ Compilación ➢ C (Curiosidades y uso específico en MINIX) ➢ Arranque de MINIX (ejemplo en PC-Intel) ➢ Inicialización del sistema ➢ Manejo de interrupciones ➢ Índice (cont) ➢ Implementación de procesos en MINIX (cont) ➢ Comunicación entre procesos ➢ Planificación en MINIX 3 ➢ Tarea del sistema ➢ Tarea de reloj ➢ Ficheros de encabezamiento ➢ Comunes ➢ MINIX ➢ Estructuras de procesos Procesos en MINIX Introducción ¿Cuáles son los servicios más importantes que suministra el núcleo de MINIX? 1- Abstracción frente a interrupciones. 2- Procesos. 3- Mensajes entre procesos. Procesos en MINIX Introducción Estructura interna Kernel: Planificación de procesos, comunicación entre procesos, operaciones con puertos de E/S, interrupciones. Tarea de reloj: Suministra servicios de temporización. Tarea del sistema: Suministra llamadas al núcleo (kernel), solo para drivers y servidores. Drivers: Suministran servicios relacionados con algún dispositivo periférico. Procesos en MINIX Introducción Estructura interna Manejador de procesos: Suministra llamadas al sistema relacionadas con la ejecución de procesos y señales. Sistema de ficheros: Suministra llamadas al sistema relacionadas con ficheros. Servidor de información: Suministra servicios para depuración y obtención del estado del sistema. Servidor de reencarnación: Arranca (y rearranca si es necesario) drivers que no se cargan al mismo tiempo que el núcleo. Procesos en MINIX Introducción Estructura interna Gestión de recursos Máquina extendida Procesos en MINIX Introducción Arranque general Gestión de procesos Arranque PC-IBM-Intel Arranque firmware Arranque dir FFFF0 Lectura cargador del SO Localización del dispositivo de arranque Cargar SO (Determinación de la partición activa) Ejecutar SO Lectura del sector de arranque en dir 7C00 Ejecución del sector de arranque (cargador) Cargar SO Ejecutar SO Procesos en MINIX Introducción Arranque MINIX Gestión de procesos Procesos en MINIX Introducción Gestión de procesos Inicialización del árbol de procesos Tarea de reloj Manejador de procesos Otros drivers Espacio del núcleo Tarea del sistema Servidor de reencarnación Init PID = 1 service floppy getty cmos is Espacio de usuario Procesos en MINIX Introducción Comunicación entre procesos Rendezvous. No hay almacenamiento intermedio (salvo para notify) send( dest, &message ); receive( source, &message ); sendrec( src_dest, &message ); notify( dest ); Procesos en MINIX Introducción Planificación Las interrupciones son los eventos que dinamizan los sistemas operativos multitarea. Las operaciones de envío de mensajes, entre otras, se realizan por medio de interrupciones activadas por el SW (traps). Las interrupciones de reloj se utilizan para controlar el tiempo de ejecución de los procesos que no se bloquean por solicitar operaciones de E/S. En MINIX se mantienen 16 colas de procesos de distinta prioridad cada una. Las prioridades en un principio respetan la siguiente desigualdad. IDLE < procesos de usuario < servidores < drivers < tareas El sistema (o, con limitaciones, un usuario) puede mover un proceso a una cola con distinta prioridad. Procesos en MINIX Introducción Planificación El quantum es otro parámetro que permite privilegiar a algunos procesos. Los procesos de usuario tienen un quantum relativamente pequeño. Los servidores y drivers suelen ejecutarse hasta que se bloquean de nuevo. Procesos en MINIX Implementación Instalación y utilización Recomendación: Utilizar el simulador de PC qemu. En debian instalar “qemu” y “qemu-launcher”. Crear una imagen de disco duro. Procesos en MINIX Implementación Teclado español. Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Arrancar el simulador haciendo que el PC virtual arranque de CD-ROM. Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Instalación y utilización Procesos en MINIX Implementación Organización del código en MINIX Organización para IBM-PC compatible con procesador Intel 386 o posterior (palabras de 32 bits). Ubicaciones Código fuente: /usr/src (src/ en adelante). Ficheros de encabezamiento: /usr/src/include (include/ en adelante). En cada directorio del árbol de ficheros fuentes hay un fichero Makefile. El directorio src/ puede ser relocalizado ya que Makefile utiliza caminos de referencia locales. Los ficheros de encabezamiento son un caso especial. ATENCIÓN AL MODIFICAR LOS FICHEROS DE ENCABEZAMIENTO Cada fichero Makefile espera encontrar los encabezamientos en /usr/include. Sin embargo, src/tools/Makefile espera los encabezamientos en /usr/src/include (borra /usr/include y lo rellena con /usr/src/include). Procesos en MINIX Implementación Organización del código en MINIX Subdirectorios adicionales include/ sys/ minix/ ibm/ Encabezamientos Posix adicionales Encabezamientos de MINIX3 Definiciones específicas para el IBM-PC Procesos en MINIX Implementación Organización del código en MINIX Subdirectorios adicionales src/ kernel/ drivers/ servers/ lib/ tools/ boot/ Nivel 1 Nivel 2 Nivel 3 Procedimientos de biblioteca Scripts para compilar MINIX3 Instalación y arranque de MINIX3 Hay otros directorios (src/test/, src/commands,...) Habrá que explorar.... Procesos en MINIX Implementación Compilar y ejecutar MINIX 3 Si ejecutamos “make” dentro del directorio scr/tools aparecen todas las opciones disponibles para compilar MINIX 3. “make install” es una opción habitual para compilar e instalar MINIX 3 (la primera vez tarda un poco) Procesos en MINIX Implementación Compilar y ejecutar MINIX 3 1. Copia src/include en /usr/include. 2. Genera ficheros objetos de src/kernel y algunos subdirectorios de src/drivers y src/server. 3. Todos los ficheros objetos de src/kernel se montan juntos para generar un único ejecutable “kernel”. 4. Todos los ficheros objetos de src/servers/pm se montan juntos para generar “pm”. 5. Todos los ficheros objetos de src/servers/fs se montan juntos para generar “fs”. 6. Otros programas que pertenecen a la imagen de arranque (“boot”) son compilados y montados en sus subdirectorios (rs, init, en src/servers, memory/, log/ tty/ en src/drivers). 7. El componente designado “driver” en la imagen de arranque puede ser cualquiera de los manejadores de disco (habitualmente disco duro). 8. Para instalar todo puede llamarse a installboot, en src/boot (supuestamente los hace make install), el cual concatena todo en un fichero ejecutable que puede ser copiado en el directorio /boot o en /boot/image. Posteriormente un programa cargador puede ubicarlo en memoria y darle control. Procesos en MINIX Implementación Compilar y ejecutar MINIX 3 La siguiente vez que se arranque MINIX hay que seleccionar: Start Custom MINIX 3 (o no teclear nada ya que es la opción por defecto) Procesos en MINIX Implementación Compilar y ejecutar MINIX 3 Organización de la memoria Procesos en MINIX Implementación C (curiosidades y uso específico en MINIX) include/ansi.h determina si el compilador utilizado cumple los requerimientos de C standard. Define la macro _PROTOTYPE para compiladores ANSI y K&R. Si el compilador es ANSI, los prototipos de funciones se especifican indicando el tipo de retorno y de los parámetros. En MINIX se definen muchos tipos de datos (ej. include/sys/types.h), pero el compilador funciona correctamente si sustituimos los mismos por los tipos subyacentes. El objetivo es únicamente hacer el código más legible (...poco más se le puede pedir al lenguaje C) Todos los tipos declarados acaban en _t y hay dos versiones, una para el compilador ansi que empieza por minúscula (ej. dev_t) y otra para el compilador K&R que empieza por mayúscula (ej. Dev_t) y que siempre es de tipo entero (...sin comentarios) Es necesario destacar que en const.h (y en otros ficheros) se utiliza la macro EXTERN, la cual es expandida como extern. Ello permite utilizar variables globales sin caer en múltiples redefiniciones de las mismas. En el fichero table.c de cada componente (kernel, servidores, etc.) se provoca la redefinición de la macro EXTERN como string vacío (al definir _TABLE), de forma que exista una única definición para cada variable global, generalmente ubicada en el fichero glo.h. Procesos en MINIX Implementación C (curiosidades y uso específico en MINIX) En C, cualquier variable o procedimiento es accesibles fuera del fichero fuente en el que se declara, salvo que se marque como static. Para ganar claridad se define PRIVATE como sinónimo de static y PUBLIC como string nulo. Ejemplos. PUBLIC void lock_dequeue(rp) Esta declaración implica que lock_dequeue puede ser invocado desde fuera del fichero fuente en el que se declara, desde cualquier fichero fuente enlazado en el mismo ejecutable binario. PRIVATE void dequeue(rp) Esta función solo puede ser invocada desde dentro del mismo fichero fuente en que se declara. Procesos en MINIX Implementación Arranque de MINIX Algunos aspectos de interés del procesador Procesos en MINIX Implementación Arranque de MINIX Configuraciones habituales de disco en relación con el arranque del sistema (no se contempla el caso de subparticiones). Procesos en MINIX Implementación Arranque de MINIX El programa de arranque boot (ubicado en /boot/boot) es un monitor que carga y arranca el sistema operativo. MINIX reserva 1024 bytes como bloque de arranque, pero solamente se cargan los primeros 512 bytes al arrancar. Los otros 512 bytes se utilizan para almacenar información de interés para el proceso de inicialización. Boot busca el nombre especificado en el parámetro image= xxxx. que por defecto es /boot/image. Si image es un fichero se carga en memoria, si es un directorio se carga el fichero más nuevo dentro de él. Cuando el sistema operativo termina devuelve el control al monitor (boot) en el caso de MINIX3. La imagen de MINIX es la concatenación de varios ficheros ejecutables (núcleo, manejador de procesos, sistema de ficheros, servidor de reencarnación, manejadores de dispositivos y por último init). Procesos en MINIX Implementación Arranque de MINIX Una vez cargado el sistema operativo en memoria se realizan algunas actividades preparatorias: “Boot” al cargar la imagen lee de ella algunos bytes de información que le indica algunas de sus propiedades. ● Se averigua información adicional para pasarla al núcleo. Información de los componentes de MINIX en la imagen es colocada en un vector en la memoria del cargador (boot) y la dirección base de dicho vector se suministra al kernel. ● Se suministra al núcleo también la dirección del monitor (boot) a la que debe volverse al terminar de ejecutarse el sistema operativo. ● La información comunicada al núcleo se transfiere por medio de la pila. Procesos en MINIX Implementación Cargador (bootstrap) Inicialización de MINIX mpx386.s (etiqueta MINIX) El cargador ha introducido en la pila datos necesarios y de interés para el núcleo. mpx386 prepara el marco de pila para poder llamar a cstart (start.c). Inicializa GDT e IDT y copia los parámetros de la pila (pasados por el cargador) a memoria del núcleo. csart mpx386.s Hace efectivas GDT e IDT con lgdt y lidt. mpx386.s salta (jmp) a main. main (main.c) Procesos en MINIX Implementación Inicialización de MINIX main fundamentalmente inicializa la tabla de procesos 1- Inicializa como libres todos los elementos de la tabla de procesos y elimina los privilegios de la tabla de privilegios. 2- Inicializan los elementos correspondientes a los procesos cargados en la imagen de arranque. main 3- Inicializa el puntero de pila de las tareas (salvo para el núcleo, denominado en ocasiones como HARDWARE). 4- Se actualizan los mapas de memoria (segmento de texto y datos) de los procesos a partir de la información que leyó el monitor de MINIX al arrancar en su memoria. 5- Se actualiza el contador de programa y el registro de estado de los procesos. 6- Se introducen en sus correspondientes colas de prioridad a los procesos. Procesos en MINIX Implementación Inicialización de MINIX Listos 7- announce 8- restart (planificamos un proceso) Procesos en MINIX Implementación Manejo de interrupciones gatedesc_s idt[IDT_SIZE] (protec.c) La tabla IDT es inicializada por prot_init (en protect.c) invocado por start.c Procesos en MINIX Implementación Manejo de interrupciones Macro genérica para el manejo de interrupciones (para el 8259 maestro). Se encuentra en mpx386.s intr_handle: manejador de interrupción genérico (kernel/i8259.c). irq_actids es distinto de cero si el manejador no ha terminado el tratamiento. Debe enmascararse la interrupción para evitar una reentrada de la misma. La instrucción “ret” realmente nos lleva a _restart, como veremos seguidamente. Procesos en MINIX Implementación irq_hook_t Manejo de interrupciones (kernel/type.h) irq_handlers[NR_IRQ_HOOKS] (kernel/glo.h) next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e notify_id policy next handler irq id proc_nr_e next handler irq NULL id notify_id proc_nr_e policy notify_id policy Procesos en MINIX Implementación Manejo de interrupciones intr_handle ejecuta todos los manejadores de los dispositivos encadenados a la misma IRQ. Para cada manejador ejecutado se verifica si ha terminado sus operaciones, en cuyo caso se borra el correspondiente bit de actividad. Nota. El manejador de interrupción de reloj es el único incorporado en el código del núcleo. Procesos en MINIX Implementación Manejo de interrupciones save llamada desde los manejadores de interrupciones cambia la pila de usuario por una pila del núcleo. En un principio no se admiten interrupciones por lo que no debería saltarse a set_restart1 “Save” retorna a la dirección almacenada antes de ser invocado (atención al cambio de pila) por medio de una instrucción jmp. “Save” introduce en la pila la dirección de _restart para que al retornar de una interrupción (hwint) se active el proceso que corresponda (cambio de contexto). Procesos en MINIX Implementación Manejo de interrupciones Si la interrupción es software: 1- No se instala el tratamiento genérico hwintxx. (ver inicialización en protect.c) 2- Para la interrupción SYS386_VECTOR se instala _s_call (mpx386.s) como tratamiento. 3- _s_call llama a sys_call (proc.c). 4- Cuando sys_call termina y el control vuelve a _s_call, no se ejecutar “ret” sino que el flujo de ejecución continua por _restart, produciéndose un cambio de contexto (al igual que ocurre con las interrupciones hardware). Procesos en MINIX Implementación Manejo de interrupciones Aspectos más importantes de la rutina _restart (mpx386.s): IF _next_ptr apunta a un descriptor de proceso distinto de 0 THEN Se planifica al proceso indicado por _next_ptr ELSE Se planifica al proceso señalado por _proc_ptr END IF Procesos en MINIX Implementación Manejo de interrupciones Procesos en MINIX Implementación Manejo de interrupciones Situaciones que pueden desembocar en la llamada a restart Procesos en MINIX Implementación Planificación en MINIX 3 Hay 15 colas de distinta prioridad. Un proceso está en una cola si se encuentra listo para ejecutar. Dentro de cada cola se aplica turno circular. Un procesos se ejecuta hasta que termina su quantum, se bloquea o finaliza. Procesos en MINIX Implementación Planificación en MINIX 3 * proc.h contiene la definición de la tabla de procesos (del núcleo). Cada entrada en la tabla de procesos respeta la estructura struc proc. Dicha estructura contiene, entre otros, los siguientes elementos: Registros del procesador (stackframe_s) ● Selector y descriptores de segmentos (código, datos y remotos). ● Privilegios (posibles fuentes y destinos de mensajes, llamadas al sistema permitidas, interrupciones pendientes, señales pendientes, temporizador para la señal de alarma, mapa de memoria remota, puertos de entrada salida permitidos, etc. La mayoría de estos campos tienen sentido para tareas y no para procesos de usuario. En este último caso se gestionan en el PM). Información detallada se encuentra en priv.h. ● Flags (p_rts_flags). Indican porque el proceso no puede ejecutarse. ● Prioridad actual y máxima. ● Número de tics para acabar el “quantum”. ● Número de tics por “quantum”. ● Tiempo invertido en ejecución de código del proceso y tiempo invertido en ejecución del sistema. ● Puntero al siguiente proceso listo para ejecutar. ● Cabecera de la lista de procesos que quieren enviar un mensaje a este proceso. ● Enlace al siguiente proceso que quiere enviar un mensaje. ● Puntero al “buffer” para mensajes. ● De quién quiere recibir un mensaje el proceso. ● A quién quiere enviar un mensaje el proceso. ● Mapa de bits para señales pendientes (el PM no espera recibir un mensaje) ● Nombre del proceso. ● Procesos en MINIX Implementación Planificación en MINIX 3 Para introducir o extraer procesos de una cola de procesos existen las funciones enqueue y dequeue (kernel/proc.c), utilizadas por ejemplo en mini_send, mini_receive y mini_notify. Enqueue: 1- Tiene como parámetro un puntero a una entrada en la tabla de procesos. 2- Determina donde insertar el proceso llamando a sched, el cual devuelve la cola en la que debe introducirse y si debe hacerlo por el principio o el final. 3- Introduce el proceso en el lugar indicado. 4- Se llama a pick_proc para planificar a un proceso. Dequeue: 1- Tiene como parámetro un puntero a una entrada en la tabla de procesos. 2- Busca y elimina el proceso indicado de la tabla de procesos. 3- Si el proceso eliminado era el que estaba ejecutándose se llama a pick_proc para seleccionar a otro proceso. Procesos en MINIX Implementación Planificación en MINIX 3 Sched verifica en primer lugar si el proceso suministrado como parámetro ha consumido su quantum. De ser así le baja la prioridad salvo que sea la mínima. Si el proceso no ha consumido su quantum se le introduce al principio de la cola de prioridad marcada por la prioridad actual del proceso. Pick_proc únicamente busca el proceso listo al principio de la cola de mayor prioridad. Si no hay ninguno IDLE siempre está listo. Ello al final actualiza next_ptr que es utilizado por restart. El manejador de interrupción de reloj, clock_handler (clock.c), actualiza prev_ptr con proc_ptr si el proceso actual ha consumido su quantum, avisando a la tarea de reloj (lock_notify), activándose por ello do_clocktick. Si el proceso actual es expulsable y ha consumido su quantum de tiempo, do_clocktick lo reubica en las colas de procesos activos llamando a dequeue y seguidamente a enqueue. Procesos en MINIX Implementación Planificación en MINIX 3 AHORA ES UN BUEN MOMENTO PARA VER EL CÓDIGO FUENTE DE: proc.c enqueue dequeue sched pick_proc clock.c clock_handler clock_task do_clocktick Procesos en MINIX Implementación Comunicación entre procesos El código de alto nivel para el envío de mensajes está en kernel/proc.c. El núcleo debe convertir en mensajes las interrupciones hardware (avisos de dispositivos) y software (llamadas al sistema). Como ya hemos visto _s_call (mpx386.s) llama a sys_call (proc.c) que en definitiva convierte una interrupción software en un mensaje. SEND BLOQUEADO POR ENVIAR A RECEIVE TRANSFERENCIA LISTO LISTO Procesos en MINIX Implementación Comunicación entre procesos RECEIVE BLOQUEADO POR RECIBIR DE SEND TRANSFERENCIA LISTO LISTO Las funciones mini_send, mini_rec y mini_notify realizan la mayor parte del trabajo en la comunicación por medio de mensajes. Procesos en MINIX Implementación Comunicación entre procesos Sys_call (proc.c) 1- Realiza diferentes comprobaciones. 2- Elabora el mensaje (mini-send o mini-receive o mini-notify o ECHO). Mini-send (proc.c) IF proceso destino está esperando este mensaje THEN Copiar el mensaje al “buffer” del destino Desbloquear al destino (enqueue) ELSE IF destino no bloqueado o no esperando a origen THEN Bloquear al proceso origen (dequeue) Encolar al proceso origen en la cola de procesos esperando enviar al destino (en descriptor de proceso destino) END IF Procesos en MINIX Implementación Comunicación entre procesos Mini_receive (proc.c) IF hay un mensaje del proceso origen THEN Adquirir el mensaje Desbloquear al proceso origen ELSE Bloquear al proceso destino END IF Mini-notify (proc.c) Muy similar a mini_send. La mayor diferencia es que el origen no se bloquea. lock_notify, lock_send, lock_enqueue, lock_dequeue hacen prácticamente lo mismo que los servicios correspondientes pero con la garantía de que las interrupciones hardware están inhibidas. Procesos en MINIX Tarea del sistema La tarea del sistema tiene su procedimiento principal en kernel/system.c (sys_task) Los procedimientos específicos de cada tipo de solicitud están en kernel/system. La tarea del sistema dispone de un vector de punteros a función (call_vec) que le permite seleccionar el código a ejecutar para cada mensaje de solicitud de servicio. Call_vec se inicializa en initialize por medio de la macro map kernel/system.c contiene varias funciones de uso en en las llamadas al núcleo o en otras partes del mismo. Procesos en MINIX Tarea del sistema Procesos en MINIX Tarea de reloj El hardware de un reloj suele estar constituido por un contador frecuentemente asociado a algun circuito de preescalado y/o postescalado. Todo el conjunto tiene una señal de entrada (la mayoría de los casos periódica) cuyos pulsos hacen evolucionar el contador. El contador suele diseñarse para poder efectuar en él lecturas y escrituras en paralelo. Hay contadores de cuenta ascendente y de cuenta ascendente. En ocasiones el circuito incluye registros para cargar un valor en el contador en el momento de alcanzarse el máximo (o mínimo) número de cuenta. Procesos en MINIX Tarea de reloj Las actividades asignadas al software de reloj suelen ser las siguientes: 1- Mantener la fecha. 2- Prevenir que los procesos consuman más tiempo del que tienen asignado. 3- Contabilizar el uso de procesador. 4- Soporte de la llamada al sistema alarm (o similar). 5- Suministro de temporizadores de guarda (watchdog) para partes del sistema. 6- Realización de perfiles, monitorización y estadísticas. Procesos en MINIX Tarea de reloj La tarea de reloj solo admite mensajes provenientes del manejador de interrupciones. La rutina do_clocktick verifica si el proceso interrumpido es expulsable y ha consumido su quantum. Procesos en MINIX Tarea de reloj La rutina do_clocktick verifica si el proceso interrumpido es expulsable y ha consumido su quantum. De ser así llama a dequeue, seguidamente a enqueue, el cual llama internamente a sched. El manejador de interrupciones previamente ha actualizado prev_ptr con el proceso interrumpido, lo que provocará una reducción de prioridad (si no está en la mínima). do_clocktic verifica si ha expirado algún temporizador de guarda en cuyo caso invoca a la función asociada. Procesos en MINIX Tarea de reloj Servicios suministrados directa o indirectamente por la tarea de reloj Procesos en MINIX Implementación #include #include #include #include #include Ficheros de encabezamiento <minix/config.h> <ansi.h> <limits.h> <errno.h> <sys/types.h> Comunes /* MUST be first */ /* MUST be second */ minix/config.h establece parámetros para “kernel”, “pm” y “fs”. * ansi.h determina si el compilador utilizado cumple los requerimientos de C standard. Define la macro _PROTOTYPE para compiladores ANSI y K&R. Si el compilador es ANSI, los prototipos de funciones se especifican indicando el tipo de retorno y de los parámetros. limits.h define varios tamaños básicos (número de bits en un entero, límites del sistema operativo, etc.) errno.h contiene los códigos de error que se devuelven a los programas de usuario, en la variable global errno, cuando falla una llamada al sistema (códigos positivos). También se utiliza para identificar algunos errores internos (códigos negativos). Se distingue de error interno o de usuario según la macro _SYSTEM. sys/types.h define tipos de datos para usar dentro de MINIX. Procesos en MINIX Implementación Ficheros de encabezamiento Comunes unistd.h define constantes y prototipos generalmente relacionados con POSIX. string.h define prototipos relacionados con el manejo de strings. signal.h define los nombres estándares de señales y algunos prototipos. relacionados con ellas fcntl.h define parámetros relacionados con operaciones de control de ficheros. termios.h define constantes, macros y prototipos de funciones relacionadas con el manejo de terminales de entrada salida. * timers.h suministra el soporte para temporizadores. stdlib.h stdio.h no son utilizados dentro de MINIX, pero se suministran por ser de uso frecuente entre los que programan en C (infelices desafortunados). * a.out.h define el formato de los ficheros ejecutables. stddef.h define algunas macros frecuentes. Procesos en MINIX Implementación Ficheros de encabezamiento Comunes sys/sigcontext.h define estructuras para preservar y restaurar un estado de operación normal del sistema cuando se activa un manejador de señal. sys/stat.h contiene declaraciones para las llamadas al sistema stat y fstat así como los prototipos de las mismas y otros relacionados. sys/dir.h describe la estructura de directorio en MINIX 3. sys/wait.h define macros utilizadas por wait y waitpid suministradas por el manejador de procesos (pm). sys/ptrace.h define las operaciones posibles con la llamada al sistema ptrace. sys/svrctl.h define estructuras de datos y macros utilizadas por svrctl, que no es una llamada al sistema, pero funciona como tal. sys/select.h suministra definiciones necesarias para svrctl. minix/ioctol.h da soporte a la llamada al sistema ioctl, la cual suministra diferentes operaciones para el control de dispositivos. Procesos en MINIX Implementación Ficheros de encabezamiento MINIX Los ficheros de include/minix son necesarios para construir MINIX sobre cualquier plataforma. Según haya diferencias puntuales en el hardware o según sea la forma en que queramos utilizar MINIX, puede ser necesario modificar minix/config.h o minix/sys_config.h (que es incluido por el anterior). minix/const.h contiene declaraciones que generalmente no es necesario modificar, pero que se utilizan en diferentes lugares. Otros ficheros const.h pueden encontrarse en otros lugares en MINIX, pero son de uso más limitado. Procesos en MINIX Implementación Ficheros de encabezamiento MINIX minix/type.h introduce algunas estructuras importantes. Unidades en las que se mide la memoria: phys_clicks utilizado por el kernel para acceder a cualquier elemento de memoria o vir_clicks para acceder a la memoria por medio de un esquema segmentado desde fuera del kernel. El esquema segmentado aprovecha el soporte para protección de memoria del procesador intel. La estructura sigmsg permite indicar al kernel, cuando se activa una señal, que la siguiente vez que planifique al proceso arranque el manejador de la señal. La estructura kinfo permite indicar la ubicación del kernel a otras partes del sistema. PM la utiliza para actualizar la tabla de procesos. * minix/ipc.h contiene la estructura message así como las definiciones de los tipos de mensajes y los prototipos de las funciones que permiten operar con los mismos. Procesos en MINIX Implementación Formatos de mensajes Ficheros de encabezamiento MINIX Procesos en MINIX Implementación Ficheros de encabezamiento MINIX minix/syslib.h contiene prototipos para permitir que algunos componentes del sistema operativo puedan acceder a los servicios de otros componentes. Son muy importantes las macros para poder realizar operaciones de entrada y salida, sys_sdevio. Poder solicitar al kernel que realice estas operaciones es fundamental para ejecutar los manejadores de dispositivos en espacio de usuario como hace MINIX 3. minix/sysutil.h suministra, entre otros servicios, printf (no printf de la librería estándar, que necesita escribir en la salida estándar y por tanto el sistema de ficheros, sino un printf utilizado por componentes del sistema) y kputc (utilizado por printf y que se declara en diferentes lugares según las necesidades de diferentes componentes del sistema). El kernel utiliza kprintf en lugar de printf. Procesos en MINIX Implementación Ficheros de encabezamiento MINIX minix/callnr.h contiene los códigos que deben enviarse en los mensajes cuando un proceso de usuario invoca una llamada al sistema. minix/com.h suministra definiciones comunes para la comunicación entre servidores y manejadores de dispositivos. minix/devio.h define tipos y constantes para facilitar el acceso a puertos de entrada salida a procesos de usuario. minix/dmap.h suministra una tabla que relaciona los números mayores de dispositivo con las funciones que los soportan. minix/u64.h da soporte a operaciones aritméticas con enteros de 64 bits, necesario para operar con direcciones de discos de alta capacidad. minix/keymap.h suministra estructuras para poder operar con distintos teclados especializados en diferentes lenguajes. * minix/bitmap.h suministra macros para operar con bits. minix/partition.h suministra información para definir una partición de disco. Procesos en MINIX Implementación Ficheros de encabezamiento MINIX Los ficheros de encabezamiento agrupados en include/ibm suministran definiciones relacionadas con la familia de computadores IBM-PC. ibm/portio.h suministra servicios para efectuar operaciones de entrada salida en puertos del PC y utilizando diferentes tipos de datos. También suministra rutinas para habilitar o deshabilitar interrupciones. ibm/interrupt.h define los puertos de entrada salida y las direcciones de memoria utilizadas por el controlador de interrupciones y BIOS. ibm/ports.h suministra las direcciones utilizadas por el teclado y el “timer”. Otros ficheros de encabezamiento, profusamente comentados (según el autor) son bios.h, memory.h, partition.h, cmos.h, cpu.h, int86.h, diskparm.h Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos A continuación vamos a ver cual es el aspecto del código de src/kernel. En primer lugar vamos a ver el contenido de kernel.h Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos * kernel/config.h permite indicar que llamadas al sistema se incluyen en el código del núcleo y cuales no. kernel/const.h suministra algunas macros para convertir a direcciones virtuales a direcciones relativas a la base del núcleo, para realizar operaciones con mapas de bits, así como se declaran las constantes que permiten establecer los privilegios para acceder al sistema de interrupciones y puertos de entrada salida. * kernel/type.h contiene, entre otras cosas, la estructura que describe como se salvan los registros del procesador en la pila (stackframe_s), así como la estructura que permite aprovechar los mecanismos de protección de espacios de los procesadores Intel 386 y posteriores, de forma que un proceso no acceda fuera de las zonas que tiene permitidas (segdesc_s). kernel/proto.h define prototipos de funciones que deben conocerse fuera del fichero en el que se definen, muchas de las cuales son dependientes del sistema. kernel/glo.h cumple el mismo cometido que el indicado con minix/glo.h. Destaca la variable aout en la que el monitor de arranque (“boot monitor”) introduce información al núcleo de los procesos en la imagen de arranque. (cont.) Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos (cont.) kinfo es utilizada para que el núcleo suministre información de si mismo a otros componentes. prev_ptr, proc_ptr, next_ptr y bill_ptr señalan a las entradas en la tabla de procesos del proceso anterior, el actual, el siguiente y el proceso al que se le tarifa el consumo de tiempo (que no siempre coincide con el proceso actual). Por último k_reenter se utiliza para controlar ejecuciones anidadas del núcleo. Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos proc.h (cont.) se definen y describen en el mismo fichero los diferentes valores que puede adquirir el campo p_rts_flags (motivos por los que un proceso no es planificable). También se especifican el número de colas para planificación y valores posibles para el campo p_priority según se trate de una tarea, proceso de usuario o proceso ocioso. Por último se definen una serie de macros que permiten un acceso más eficiente a la tabla de procesos. sconst.h mantiene información muy relacionada con la existente en proc.h con la intención de ser utilizada desde ensamblador. Al realizar algún cambio a proc.h es necesario verificar si es necesario realizar alguna modificación en sconst.h priv.h (como ya hemos comentado al hablar de proc.h) contiene la información de privilegio que aparece en cada entrada de la tabla de procesos. Al pulsar la tecla F4 se fuerza un volcado parcial de dicha información. (P:expulsable, B:facturable, S:sistema, en cuanto a los traps, E:eco, S:enviar, R:recibir, B:enviar_recibir, N:notificación. Por último, el mapa de bits indica a quien se puede enviar mensajes). Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos protect.h define información relativa a tablas de descriptores referenciadas por registros del procesador. Los procesadores Intel suministran niveles de privilegio (a partir del 80286), los cuales son aprovechados en MINIX. Los procesadores Pentium (muy habituales en PC actuales) suministran cuatro niveles de protección, de los cuales MINIX utiliza 3. INTR_PRIVILEGE. En este nivel puede accederse a cualquier posición de memoria y a cualquier registro del procesador. Trabajan en este nivel los tratamientos de interrupción y el código encargado de efectuar cambios de contexto. ● TASK_PRIVILEGE. Nivel en el que se permite acceder a los puertos de entrada salida, pero no se permite modificar los registros especiales del procesador, como por ejemplo los que apuntan a las tablas de descriptores. ● USER_PRIVILEGE. Los procesos en este nivel no pueden ejecutar intrucciones privilegiadas (por ejemplo las que permiten realizar operaciones de entrada salida, cambiar las asignaciones de memoria o cambiar niveles de privilegio). ● Procesos en MINIX Implementación Ficheros de encabezamiento Estructuras de procesos Primera aproximación al código en C (no más ficheros de encabezamiento ....... de momento). * table.c no contiene código ejecutable, pero el fichero objeto que se genera al compilarlo (table.o) contiene todas las estructuras de datos del núcleo. La mayoría de dichos datos se encuentran en glo.h donde se redefine EXTERN como string nulo para conseguir la correcta asignación de memoria para dichas variables. Se definen también en table.c constantes que determinan a quien se pueden enviar mensajes y notificaciones. Seguidamente se establecen máscaras que determinan que llamadas al núcleo se permiten a que procesos. A continuación se especifica la tabla de la imagen de arranque en la que se incluyen detalles para inicializar correctamente los procesos que configuran la imagen de arranque del sistema. Por último se verifica (en tiempo de compilación) el correcto tamaño de la tabla de la imagen de arranque. Procesos en MINIX Bibliografía Referencia fundamental [1] Tanenbaum, A.S.; Woodhull, A.S. (2006): Operating Systems. Design and Implementation. Prentice Hall. Otras referencias [2] (1999): Intel Architecture Software Developer's Manual. Vol1. Basic Architecture. Intel Corporation. [3] (1999): Intel Architecture Software Developer's Manual. Vol3. System Programming. Intel Corporation. [4] (1988): 8259A Programmable Interrupt Controller. Intel Corporation.