Plug & Pray
Plug & Pray
-1C2026 -
Versión 1.0
Índice
Índice
Historial de Cambios
Objetivos del Trabajo Práctico
Características
Evaluación del Trabajo Práctico
Deployment y Testing del Trabajo Práctico
Definición del Trabajo Práctico
¿Qué es el trabajo práctico y cómo empezamos?
Arquitectura del sistema
Aclaración importante
Módulo: Kernel Scheduler
Lineamiento e Implementación
Planificación de Procesos
Planificación de Largo Plazo
Planificación de Mediano Plazo
Planificación de Corto Plazo
Desalojo por compactación
Mutex
Herencia de prioridades
IO
Sleep
STDIN
STDOUT
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Módulo: Kernel Memory
Lineamiento e Implementación
Memoria de Instrucciones y Contextos
Contexto de Ejecución
Archivos de pseudocódigo
Memoria de Usuario o Datos
Esquema de memoria y Estructuras
Desconexión de un Memory Stick
Operaciones
Creación de Proceso
Creación de Segmento
Algoritmos de selección de huecos
Compactación
Eliminación de Segmento
Suspensión de Proceso
Des-suspensión de Proceso
Finalización de Proceso
Lectura de datos
Escritura de datos
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Módulo: CPU
Lineamiento e Implementación
Registros de la CPU
Ciclo de Instrucción
Fetch
Decode
Ejemplos de instrucciones a interpretar
Execute
Check Interrupt
MMU
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Módulo: Memory Stick
Lineamiento e Implementación
Operaciones
Lectura de datos
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Módulo: IO
Lineamiento e Implementación
STDIN
STDOUT
SLEEP
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Módulo: SWAP
Lineamiento e Implementación
Operaciones
Lectura de bloque
Logs mínimos y obligatorios
Archivo de Configuración
Ejemplo de Archivo de Configuración
Descripción de las entregas
Check de Control Obligatorio 1: Conexión inicial
Check de Control Obligatorio 2: Planificación
Check de Control Obligatorio 3: CPU Completa y Memoria
Entregas Finales
Historial de Cambios
v1.0 (07/04/2026) Publicación del enunciado
Objetivos del Trabajo Práctico
Mediante la realización de este trabajo se espera que el alumno:
Debido al fin académico del trabajo práctico, los conceptos que se verán reflejados son, en general,
versiones simplificadas o alteradas de los componentes reales de hardware y de sistemas operativos
vistos en las clases, a fin de resaltar aspectos de diseño o simplificar su implementación.
Invitamos a los alumnos a leer las notas y comentarios al respecto que haya en el enunciado,
reflexionar y discutir con sus compañeros, ayudantes y docentes al respecto.
Características
● Modalidad: grupal (5 integrantes ± 0) y obligatorio
La primera etapa consistirá en las pruebas de los programas desarrollados en el laboratorio. Previo a
la evaluación final se subirán una serie de pruebas para que los alumnos puedan validar el correcto
funcionamiento de su trabajo práctico. Queda aclarado que para que un trabajo práctico sea
considerado evaluable, el mismo debe proporcionar logs de su funcionamiento de la forma más clara
posible, para ello se les proveerá en cada módulo un listado de logs mínimos y obligatorios.
La segunda etapa se dará en caso de aprobada la primera y constará de un coloquio individual, con
el objetivo de validar y afianzar la aplicación de los conocimientos adquiridos durante el desarrollo
del trabajo práctico y definir la nota de cada uno de los integrantes del grupo, por lo que se
recomienda que la carga de trabajo se distribuya de la manera más equitativa posible.
Cabe aclarar que el trabajo equitativo no asegura la aprobación de la totalidad de los integrantes,
sino que cada uno tendrá que defender y explicar tanto teórica como prácticamente lo desarrollado
y aprendido a lo largo de la cursada.
La defensa del trabajo práctico (o coloquio) consta de la relación de lo visto durante la teoría con lo
implementado. De esta manera, una implementación que contradiga lo visto en clase o lo escrito en
el documento es motivo de desaprobación del trabajo práctico. Esta etapa al ser la conclusión del
todo el trabajo realizado durante el cuatrimestre no es recuperable.
Todo esto estará detallado en el documento de pruebas que se publicará cercano a la fecha de
Entrega Final. Archivos y programas de ejemplo se pueden encontrar en el repositorio de la cátedra.
Finalmente, es mandatoria la lectura y entendimiento de las Normas del Trabajo Práctico donde se
especifican todos los lineamientos de cómo se desarrollará la materia durante el cuatrimestre.
Definición del Trabajo Práctico
Esta sección se compone de una introducción y definición de carácter global sobre el trabajo
práctico. Posteriormente se explicarán por separado cada uno de los distintos módulos que lo
componen, pudiéndose encontrar los siguientes títulos:
Cada módulo contará con un listado de logs mínimos y obligatorios los cuales deberán realizarse
utilizando la biblioteca de so-commons-library provista por la cátedra y los mismos deberán estar
como LOG_LEVEL_INFO, pudiendo ser extendidos por necesidad del grupo utilizando
LOG_LEVEL_DEBUG. En la descripción de los logs mínimos y obligatorios, se utiliza la notación de <>
para encerrar los valores que irán variando de acuerdo a la ejecución, pero los caracteres menor y
mayor ( < > ) no deberán estar presentes en el log final.
En caso de no cumplir con los logs mínimos y/o no guardarlos en archivo, se considerará que el TP
no es apto para ser evaluado y por consecuencia el mismo estará desaprobado.
Cabe destacar que en ciertos puntos de este enunciado se explicarán exactamente cómo deben ser
las funcionalidades a desarrollar, mientras que en otros no se definirá específicamente, quedando su
implementación a decisión y definición del equipo. Se recomienda en estos casos siempre consultar
en el foro de github, dado que las justificaciones deberán ser expuestas en el coloquio.
Para el desarrollo del mismo se decidió la creación de un sistema bajo la metodología Iterativa
Incremental donde se solicitarán en una primera instancia la implementación de ciertos módulos
para luego poder realizar una integración total con los restantes.
Recomendamos seguir el lineamiento de los distintos puntos de control que se detallan al final de
este documento para su desarrollo. Estos puntos están planificados y estructurados para que sean
desarrollados a medida y en paralelo a los contenidos que se ven en la parte teórica de la materia.
Cabe aclarar que esto es un lineamiento propuesto por la cátedra y no implica impedimento alguno
para el alumno de realizar el desarrollo en otro orden diferente al especificado.
IO
CPU IO
STDIN
CPU STDIN
IO
CPU
Kernel
Scheduler
NOTAS:
● El sentido de las flechas indica dependencias entre módulos. Ejemplo: al momento de iniciar
la ejecución del Kernel Scheduler es necesario contar con el Módulo Kernel Memory ya
iniciado.
● Cada uno de estos Módulos será un programa realizado en lenguaje C, compilado y
ejecutado en la Máquina Virtual, por lo que será un proceso real del sistema operativo.
● A lo largo de este enunciado llamaremos Proceso (con P mayúscula) a los procesos
simulados que se planificarán y ejecutarán dentro de la implementación de este trabajo
práctico.
Aclaración importante
Desarrollar únicamente temas de conectividad, serialización, sincronización o los módulos IO, SWAP
o Memory Stick son insuficientes para poder entender y aplicar los distintos conceptos de la materia.
Dicho caso será un motivo de desaprobación directa.
Módulo: Kernel Scheduler
Dentro de este TP, el Kernel Scheduler será el módulo encargado de gestionar la planificación de los
Procesos a lo largo de las diferentes pruebas que se tengan que realizar.
Lineamiento e Implementación
El Kernel Scheduler contará con un primer parámetro que será el Path al Proceso Inicial, el cual será
el PID 0 del sistema, que siempre tendrá prioridad máxima, y a partir del cual se crearán los demás
Procesos.
Al iniciar el módulo, el mismo se deberá conectar con el módulo Kernel Memory y, una vez que
establezca dicha conexión, deberá crear un servidor multihilo para atender de forma concurrente las
peticiones de las CPUs y de los módulos de IO.
A lo largo de la ejecución se podrán desconectar y conectar nuevas CPUs, por lo que se deberá
mantener la escucha a nuevas conexiones siempre activa.
Planificación de Procesos
Una vez creado el servidor para escuchar las conexiones, el Kernel Scheduler deberá cumplir con las
tareas de planificación de largo, mediano y corto plazo detalladas más adelante. La implementación
de los mismos es una decisión de diseño que deberá tomar el grupo, pero deberá ser capaz de
gestionar un modelo de 7 estados:
BLOC
K
SUSP SUSP
READ BLOC
Y K
Planificación de Largo Plazo
Se encargará de ingresar Procesos de NEW a READY. Dado que los Procesos inician sin memoria
asignada, este pasaje se podrá realizar sin ninguna limitación.
En algún momento de la ejecución es posible que se reciba una notificación del Kernel Memory de
que se detectó corrupción en una parte de la memoria. Ante este evento, se deberán finalizar todos
los Procesos y finalizar el Kernel Scheduler con motivo de Blue Screen of Death (BSOD).
Para realizar la transición del estado BLOCK a SUSP. BLOCK, por cada Proceso que entre al estado
BLOCK, se deberá esperar un tiempo determinado por archivo de configuración. Si al transcurrir
dicho tiempo el Proceso aún continúa en estado BLOCK, se lo deberá mover al estado SUSP. BLOCK.
En caso de que se libere memoria, se agregue un memory stick nuevo, o se compacte la misma, se
recorrerán todos los Procesos suspendidos por orden de prioridad y se irán des-suspendiendo si
cuentan con espacio disponible para re-crear todos sus segmentos sin disparar una compactación.
En caso de contar con más de un Proceso suspendido con la misma prioridad, se evaluará primero el
que lleve mayor tiempo suspendido.
Vamos a estar utilizando uno de los tres posibles algoritmos de planificación definidos, los cuales van
a ser FIFO, RR y Colas Multinivel (no retroalimentadas). El algoritmo a utilizar será elegible por
archivo de configuración y no cambiará a lo largo de una prueba.
La planificación basada en Colas Multinivel definirá una cola por cada nivel de prioridad dentro del
sistema. El algoritmo (FIFO o RR) a utilizar dentro de cada cola estará especificado dentro del archivo
de configuración. Las prioridades comenzarán en 0, y no se deberán planificar Procesos que tengan
un nivel de prioridad fuera del rango definido dentro del archivo de configuración. Por ejemplo, si se
definen 4 colas en la configuración, solamente se planificarán prioridades de la 0 a la 3.
En los algoritmos de FIFO y RR la prioridad no tendrá injerencia alguna, mientras que en el algoritmo
de Colas Multinivel, al momento de llegar un Proceso, y si el desalojo entre colas está habilitado, se
deberá validar si se encuentra ejecutando un Proceso con menor prioridad. En caso de que así sea,
se deberá desalojar al Proceso menos prioritario para darle lugar al más prioritario que acaba de
llegar.
Al recibir este pedido, el Kernel Scheduler enviará la solicitud de desalojo a todas las CPU y no
enviará ningún otro Proceso a ejecutar hasta que reciba la confirmación por parte del Kernel
Memory que finalizó la compactación. Los Procesos desalojados, excepcionalmente, serán colocados
al principio de la cola de READY.
Una vez finalizada la misma se procederá a replanificar todos los Procesos de acuerdo al algoritmo
definido.
Mutex
Dentro del módulo también se gestionarán los semáforos de tipo Mutex que tendrá nuestro
lenguaje de scripting creado con fines didácticos.
Estos semáforos tendrán la particularidad de que, al ser de tipo Mutex, solo un Proceso los podrá
tener tomado al mismo tiempo y el resto de Procesos deberán aguardar a ser atendidos.
Herencia de prioridades
A lo largo de la ejecución puede darse la situación en la que un Proceso de prioridad baja tome un
Mutex libre, y que luego de esto, un Proceso con mayor prioridad intente tomar el mismo mutex. Al
estar previamente tomado por el Proceso de menor prioridad, este segundo queda bloqueado.
Ante este evento, donde un Proceso de una prioridad mayor queda bloqueado a la espera de un
Proceso con prioridad menor, este último heredará temporalmente la prioridad del Proceso con
mayor prioridad que se encuentre bloqueado esperando el Mutex. Una vez que el Proceso de baja
prioridad libere el Mutex, volverá a tener su prioridad original.
IO
Las IO dentro del entorno de nuestro trabajo práctico pueden ser 3: SLEEP, STDIN y STDOUT. En
todos los casos, al momento de que llegue la petición de la CPU, el proceso pasará del estado EXEC al
estado BLOCK y el Kernel Scheduler deberá enviar un nuevo Proceso a ejecutar si lo hubiera.
Sleep
Para las IO de tipo Sleep se recibirá de la CPU un tiempo en milisegundos que deberá estar el
Proceso en la IO de tipo Sleep.
STDIN
Para las IO de tipo STDIN, se recibirán por parte de la CPU un tamaño total a leer y la dirección lógica
donde se deberá guardar el contenido leído.
Se deberá solicitar a la IO de tipo STDIN que le solicite al usuario ingresar el total a leer y luego,
cuando este retorne los caracteres leídos, se deberán enviar al Módulo Kernel Memory para que
este las escriba en donde corresponda.
STDOUT
En el caso de las IO de tipo STDOUT, el Kernel Scheduler recibirá de parte de la CPU la dirección
lógica y el tamaño a leer. Una vez que este le retorne todos los bytes, deberá pedirle esta
información al Kernel Memory para luego, enviársela a la IO de tipo STDOUT.
Desalojo por fin de Quantum: “## (<PID>) - Desalojado por fin de quantum”
Archivo de Configuración
Lineamiento e Implementación
Al iniciar creará un servidor multihilo que se encargará de gestionar de manera concurrente las
peticiones del Kernel Scheduler y las CPUs, así como también esperará las conexiones de los
diferentes Memory Sticks y del SWAP.
A lo largo de la ejecución se podrán conectar nuevas CPUs y Memory Sticks, por lo que se deberá
mantener la escucha a nuevas conexiones siempre activa.
Contexto de Ejecución
Por cada PID del sistema se deberá almacenar un contexto de ejecución, el cual consiste en una copia
de todos los registros de la CPU y la tabla de segmentos asociada a dicho Proceso.
Este módulo deberá mantener el contexto de ejecución de cada Proceso del sistema. Deberá ser
capaz de enviar y/o recibir el contexto de ejecución hacia/desde el módulo CPU cuando este se lo
solicite.
Archivos de pseudocódigo
Los archivos de pseudocódigo serán archivos de texto, los cuales contendrán las instrucciones que
ejecutan las CPUs, estando estas separadas por el caracter ‘\n’.
Por cada PID del sistema se tendrá un archivo de pseudocódigo, para lo que cada grupo deberá
implementar una estructura que le permita asociar qué PID tiene asociado qué archivo de
pseudocódigo.
El Kernel Memory deberá ser capaz de enviar la instrucción correspondiente a cada pedido de la CPU
sin haber una restricción específica de cómo se deben obtener las mismas (queda a criterio de cada
grupo la implementación de esta sección).
Memoria de Usuario o Datos
Para el almacenamiento de los datos se utilizarán los módulos Memory Stick, los cuales al momento
de conectarse deberán informarle su tamaño al módulo Kernel Memory. Una vez recibido el tamaño,
se deberá añadir al final de la lista de Memory Sticks conectados, ampliando el tamaño máximo de la
memoria total.
Al momento de que se conecte un nuevo Memory Stick y se amplíe el tamaño total de la memoria,
se deberá notificar al Kernel Scheduler que se dispone de más memoria.
Operaciones
El Kernel Memory, al ser el módulo que gestiona la memoria del sistema y de los Procesos, puede
aceptar una serie de operaciones que describiremos a continuación.
Creación de Proceso
Para esta operación se va a recibir un PID y el path de un archivo de instrucciones, relativo 1 al path
base configurado por archivo de configuración. Con los datos recibidos, el Módulo Kernel Memory
deberá crear el contexto de ejecución del Proceso, inicializando todos los registros asociados con el
valor 0.
Creación de Segmento
Al momento de crear un segmento el Kernel Memory recibirá como parámetro el PID del Proceso,
un ID de segmento y el tamaño que debe tener el nuevo segmento.
Los Algoritmos a implementar son Best Fit y Worst Fit, y la elección del mismo se hará por medio del
archivo de configuración del Kernel Memory.
Una vez recibida la confirmación por parte del Kernel de que se desalojaron las CPUs comenzará el
proceso de compactación, en el cual se tendrán que reordenar todos los segmentos de memoria al
principio de la misma. Esto puede resultar en que algunos segmentos se muevan parcial o
totalmente de Memory Stick, debiendo actualizar las tablas de segmentos de todos los Procesos.
Eliminación de Segmento
Al momento de eliminar un segmento se recibirá como parámetro el PID y el ID del segmento a
eliminar y se procederá simplemente a eliminar dicha entrada en la tabla de segmentos del proceso.
Por último, se marcará ese espacio como libre en la memoria.
Suspensión de Proceso
Al momento de suspender un Proceso se deberán mover todos sus segmentos de los Memory Sticks
a bloques dentro del Módulo SWAP. Para ello se irán moviendo de a 1 segmento y se liberará la
memoria una vez que el mismo se encuentra copiado.
Es responsabilidad de cada grupo definir las estructuras necesarias para poder saber en qué bloques
se encuentra cada segmento. Los bloques de SWAP se asignan por segmento, por lo que no puede
existir un bloque que contenga información de 2 segmentos distintos.
Des-suspensión de Proceso
Al momento de des-suspender un Proceso se deberán restaurar todos los segmentos que se
encuentran almacenados en SWAP a la memoria principal. Para ello se deberá regenerar
nuevamente la tabla de segmentos que se encuentra en el contexto de ejecución del Proceso.
Finalización de Proceso
Esta operación se utiliza para finalizar un Proceso, por lo que solamente va a recibir un PID y a partir
de este PID recibido se deberán liberar todos los segmentos asociados al Proceso y todas las
estructuras asociadas al mismo.
Lectura de datos
Esta operación va estar asociada a un pedido directo del Kernel Scheduler, que va a oficiar de
intermediario entre la IO de tipo STDOUT y el Kernel Memory, pidiéndole a este último una cantidad
de bytes determinada, que se encuentra almacenada en uno o varios Memory Sticks.
Va a recibir como parámetros una dirección lógica y el tamaño a leer, por lo que deberá realizar la
traducción de la dirección lógica a física para llevar a cabo la operación.
Escritura de datos
Esta operación va a estar asociada a un pedido directo del Kernel Scheduler que va a oficiar de
intermediario entre la IO de tipo STDIN y el Kernel Memory, pidiéndole a este último que escriba una
serie de bytes en uno o varios Memory Sticks.
Va a recibir como parámetros una dirección lógica y una cantidad de bytes a escribir, por lo que
deberá realizar la traducción de la dirección lógica a física para llevar a cabo la operación.
Archivo de Configuración
Lineamiento e Implementación
Al momento de ejecutar un CPU se debe indicar por argumento cuál es su “identificador” para poder
identificarla de los demás.
El módulo CPU es el encargado de interpretar y ejecutar las instrucciones recibidas por parte del
Kernel Memory. Para ello, ejecutará un ciclo de instrucción simplificado que cuenta con los pasos:
Fetch, Decode, Execute y Check Interrupt.
Para cada CPU se deberá tener un archivo de log y archivo de configuración independientes, que
deberán contar con el identificador pasado por parámetro para poder identificar a qué CPU
corresponde el archivo de log que se está leyendo. Las CPUs deberán conectarse al Kernel
Scheduler, al Kernel Memory y a los diferentes Memory Sticks. Estos últimos se podrán ir
conectando a lo largo de la ejecución, por lo que es importante que el grupo defina una estrategia
entre el Kernel Memory y las CPUs para que éstas conozcan todos los Memory Sticks que existen
cuando sea necesario.
Una vez establecidas todas las conexiones, la CPU se quedará a la espera de recibir un PID de parte
del Kernel Scheduler. Una vez recibido, la CPU deberá solicitarle al Kernel Memory el contexto de
ejecución y comenzar el primer ciclo de instrucción.
A la hora de ejecutar instrucciones que requieran interactuar directamente con la Memoria, tendrá
que traducir las direcciones lógicas (propias del proceso) a direcciones físicas (propias de la
memoria). Para ello simulará la existencia de una MMU.
Registros de la CPU
En la implementación de nuestra CPU, se utilizará una serie de registros para poder modelar la
operatoria de una CPU real simplificada; es decir, vamos a contar con registros similares a los vistos
en Arquitectura de Computadores y algunos registros creados por nosotros mismos a fin de poder
facilitar las pruebas.
En la siguiente tabla está el detalle de los registros que deberá tener nuestra CPU, en la cual estará
detallado el tamaño del mismo y qué tipo de dato se recomienda para su implementación:
Ciclo de Instrucción
Fetch
La primera etapa del ciclo consiste en buscar la próxima instrucción a ejecutar. En este trabajo
práctico cada instrucción deberá ser pedida al módulo Kernel Memory utilizando el Program Counter
(también llamado Instruction Pointer) que representa el número de instrucción a buscar relativo al
Proceso en ejecución.
Decode
Esta etapa consiste en interpretar qué instrucción es la que se va a ejecutar y si la misma requiere de
una traducción de dirección lógica a dirección física.
1 NOOP
2 SET AX 6
3 SET BX 2
4 SET PC 5
5 SUM AX BX
6 SUB AX BX
7 JNZ AX 4
2 En caso de que se realice una modificación de este registro en una operación, se omitirá el paso de sumar 1
al final del ciclo de instrucción
8 COPY_MEM AX
9 MOV_IN EDX
10 MOV_OUT EDX
11 MUTEX_CREATE MUTEX_1
12 MUTEX_LOCK MUTEX_1
13 MUTEX_UNLOCK MUTEX_1
14 MEM_ALLOC 0 64
15 MEM_FREE 0
16 SLEEP 25000
17 STDOUT AX BX
18 STDIN CX DX
19 INIT_PROC proceso1 3
20 EXIT
Execute
En este paso se deberá ejecutar lo correspondiente a cada instrucción:
Las siguientes instrucciones se considerarán Syscalls, ya que las mismas no pueden ser resueltas por
la CPU y depende de la acción del Kernel Scheduler para su realización. A diferencia de la vida real
donde la llamada es a una única instrucción, para simplificar la comprensión de los scripts, vamos a
utilizar un nombre diferente para cada Syscall. La descripción de lo que hace cada una va a estar
detallada en el Kernel Scheduler.
Es importante tener en cuenta que, al finalizar el ciclo de instrucción, el Program Counter (PC)
deberá ser actualizado sumándole 1, siempre y cuando este no haya sido modificado por la
instrucción ejecutada anteriormente.
Check Interrupt
En este momento, se deberá chequear si el Kernel Scheduler nos envió una interrupción al PID que
se está ejecutando. En caso afirmativo, se actualiza el contexto de ejecución en el Kernel Memory y
se le devuelve el PID al Kernel Scheduler con el motivo de la interrupción. Caso contrario, se descarta
la interrupción.
MMU
A la hora de traducir direcciones lógicas a físicas, la CPU debe tomar en cuenta que el esquema de la
memoria de este sistema es de Segmentación, por lo tanto, las direcciones lógicas se interpretarán
de la siguiente manera:
Estas traducciones, a diferencia de lo que se hace en los ejercicios prácticos que se ven en clases y se
toman en los parciales, no se realizarán en binario, ya que es más cómodo utilizar números enteros
en sistema decimal para ver los valores. Por lo tanto, la operatoria sería más parecida a la siguiente:
En algunas traducciones es posible que una petición de lectura o escritura abarque más de 1
Memory Stick. Será responsabilidad del grupo dividir estas peticiones de acuerdo a los diferentes
Memory Sticks involucrados, teniendo en cuenta que las direcciones físicas de los Memory Stick
arrancan a partir del 0. Luego se deberá consolidar el resultado de la operación para que la misma se
considere como una única operación.
Archivo de Configuración
Lineamiento e Implementación
El módulo Memory Stick es el encargado de atender las diferentes peticiones de lectura y escritura
de las CPUs o del Kernel Memory. Para ello, primero deberá conocer su tamaño, el cual deberá ser
ingresado como un parámetro al iniciar el módulo.
Una vez leído el tamaño de memoria que representa este Proceso, reservará con malloc() dicha
cantidad de memoria y deberá conectarse al Kernel Memory. En caso de que la conexión con Kernel
Memory sea exitosa, deberá quedarse a la espera de las conexiones de las diferentes CPUs para que
estas le hagan pedidos de lectura y escritura sobre la memoria reservada con malloc().
Operaciones
El módulo Memory Stick, solamente podrá responder a 2 operaciones que consisten en la escritura o
lectura de los datos. En todos los casos las direcciones físicas arrancarán en 0 para el Memory Stick
en cuestión.
Escritura de datos
Para esta operación se recibirá la dirección física a partir de la cual se deberá escribir y el contenido a
escribir. Los grupos podrán añadir información extra para facilitar la implementación de esta
operación.
Como resultado de esta operación deberán devolver una confirmación al módulo que los haya
llamado.
Lectura de datos
El módulo Memory Stick recibirá una dirección física y un tamaño a leer. Como resultado de esta
operación deberá devolver los bytes leídos.
Lineamiento e Implementación
El módulo IO es el encargado de simular las operaciones de Entrada/Salida, para ello al iniciar deberá
leer como parámetro de entrada el nombre el cual identificará a la interfaz de IO.
Una vez leído el tipo de IO, deberá conectarse al Kernel Scheduler y quedarse a la espera de las
peticiones que este le pueda hacer. Al momento de recibir la petición de IO el comportamiento será
el definido a continuación de acuerdo al tipo de IO recibido por parámetro al iniciar.
STDIN
Recibirá una cantidad de caracteres (bytes) que deberá leer por teclado y se quedará esperando el
input del usuario, el cual finalizará cuando éste pulse la tecla Enter. En caso de que la cadena de
caracteres sea mayor al tamaño recibido, se deberá cortar el contenido a la cantidad de bytes
solicitada. En caso de que sea menor, se completará con valores ‘\0’ hasta alcanzar el límite
indicado para devolver dicha información al Kernel Scheduler.
STDOUT
Recibirá una cadena de caracteres (bytes) la cual deberá imprimir por pantalla y en el archivo de Log.
Una vez impreso el log deberá informar al Kernel que la IO finalizó correctamente.
SLEEP
Recibirá un tiempo en milisegundos como parámetro adicional para ejecutar un usleep()3 de
dicho tiempo, antes de contestarle al Kernel Scheduler que la IO finalizó correctamente.
Solo para STDIN: “## PID: <PID> - Ingrese <CANTIDAD A LEER> caracteres:”
Archivo de Configuración
Lineamiento e Implementación
Para poder almacenar la memoria de los Procesos suspendidos, el módulo SWAP contará con un
único archivo cuyo path y tamaño serán definidos por los parámetros SWAP_FILE_PATH y
SWAP_FILE_SIZE del archivo de configuración. El archivo que contiene la información de los Procesos
se asume que inicia siempre libre, no siendo necesario que su contenido se tenga que limpiar
explícitamente.
Este archivo se dividirá internamente en bloques de un tamaño definido también por archivo de
configuración (BLOCK_SIZE).
Al iniciar, el módulo deberá informar al módulo Kernel Memory el tamaño de bloque y el tamaño
total del SWAP.
Dado que la administración del espacio de SWAP es tarea del Kernel Memory, este módulo no
deberá contar con ninguna estructura administrativa más allá de lo necesario para leer y/o escribir el
archivo utilizado para persistir la información.
Operaciones
El módulo SWAP solamente podrá responder a 2 operaciones que consisten en la escritura o lectura
de los datos. En ambos casos las operaciones siempre tendrán el tamaño de 1 bloque.
Escritura de bloque
Como resultado de esta operación se deberá devolver una confirmación al Kernel Memory de que la
escritura fue exitosa.
Lectura de bloque
Para esta operación el módulo SWAP recibirá el número de bloque a leer y como resultado de esta
operación deberá devolver los bytes leídos.
Archivo de Configuración
Fecha: 18/04/2026
Objetivos:
● Comprender la arquitectura y la comunicación entre los módulos del sistema.
● Todos los módulos están creados y son capaces de establecer conexiones entre sí mediante sockets.
Propósito académico:
● Familiarizarse con el entorno de desarrollo y el repositorio.
● Aprender a utilizar las Commons, principalmente las funciones para listas, archivos de configuración y logs.
Fecha: 23/05/2026
Objetivos:
● Módulo Kernel Scheduler:
○ Planificación de corto y largo plazo con FIFO y RR.
○ Administración del estado BLOCK y las colas de los módulos de IO.
○ Administración de los Mutex y sus colas de Procesos sin herencia de prioridades.
● Módulo CPU:
○ Realiza el ciclo de instrucción completo siendo capaz de interpretar y ejecutar instrucciones (Sin
memoria).
Fecha: 20/06/2026
Objetivos:
● Módulo Kernel Scheduler:
○ Planificación de corto y largo plazo completa.
○ Implementación de Herencia de Prioridades.
Entregas Finales