This project aims to simulate a distributed system, focusing on process scheduling, system request handling, and efficient management of memory and file systems. It is the practical work of the subject "Operating Systems" of the "Information Systems Engineering" degree at UTN.
The Kernel module is a crucial component of this simulation, responsible for managing the execution of various processes generated through its API.
-
Process Management
- Initiate system processes
- Manage process lifecycle
- Handle process state transitions
-
Resource Management
- Manage system resources as defined in the configuration file
- Handle WAIT and SIGNAL operations for resources
-
I/O Interface Management
- Manage connections with dynamically connected I/O interfaces
- Handle I/O requests from processes
-
Memory and CPU Interaction
- Manage requests to the Memory module for process creation and deletion
- Schedule process execution on the CPU module
- Start process
cd /path/to/SO-Panza_Confianza/prueba/ejecutablesSH ./crear_proceso.sh pid /path/to/SO-Panza_Confianza/prueba/scripts_memoria/DESIRE_PROCESS
- End process
./finalizar_proceso.sh pid
- Get process status
./estado_proceso.sh pid
- Start scheduling
./iniciar_plani.sh
- Stop scheduling
./detener_plani.sh
- List processes
./listar_procesos.sh
This module is estimated to comprise approximately 35% of the overall project workload. Demonstrating theoretical knowledge and practical implementation of this module is crucial for project approval.
The CPU module in this project simulates a simplified version of a real CPU's instruction cycle. It is responsible for interpreting and executing instructions from the Execution Contexts received from the Kernel.
The CPU implements a simplified instruction cycle with the following steps:
- Fetch: Retrieve the next instruction from Memory using the Program Counter.
- Decode: Interpret the instruction and determine if address translation is needed.
- Execute: Perform the operation specified by the instruction.
- Check Interrupt: Verify if the Kernel has sent an interrupt for the current process.
The MMU is responsible for translating logical addresses to physical addresses. It uses a paging scheme where logical addresses are composed of:
[page_number | offset]
The translation can be performed as follows:
- page_number = floor(logical_address / page_size)
- offset = logical_address - page_number * page_size
The TLB is implemented to speed up the translation of logical addresses to physical addresses. Its structure includes:
[pid | page | frame]
TLB configuration:
- The number of entries and replacement algorithm are specified in the CPU configuration file.
- Number of entries: Integer (0 disables TLB)
- Replacement algorithms: FIFO or LRU
The CPU supports various instructions, including but not limited to:
- SET, MOV_IN, MOV_OUT: Memory operations
- SUM, SUB: Arithmetic operations
- JNZ: Conditional jump
- RESIZE: Memory allocation
- WAIT, SIGNAL: Resource management
- I/O operations (e.g., IO_STDIN_READ, IO_STDOUT_WRITE)
- File system operations (e.g., IO_FS_CREATE, IO_FS_DELETE)
- EXIT: Process termination
- The CPU module comprises approximately 15% of the overall project workload.
- Implement proper error handling for invalid instructions or memory access.
- Ensure accurate updating of the Execution Context throughout the instruction cycle.
- Implement the TLB with the specified replacement algorithms.
- Handle logical to physical address translation correctly, considering the paging scheme.
The Memory module is responsible for managing the system's memory, including instruction storage, user space, and page tables. It implements a simple paging scheme and handles various memory-related operations.
- Instruction Memory
- User Space Memory
- Page Tables
- Communication interfaces with Kernel, CPU, and I/O Interfaces
- Stores instructions from pseudo-code files
- Provides instructions one at a time to the CPU upon request
- Simulates memory access delay as specified in the configuration file
- Creates necessary administrative structures for a new process
- Frees memory space occupied by the terminated process
- Marks frames as free without overwriting their content
- Responds with the frame number corresponding to the queried page
Handles two scenarios:
- Process Expansion
- Expands the process size at the end
- Responds with "Out Of Memory" error if unable to allocate required frames
- Process Reduction
- Reduces the process size from the end
- Frees unused pages as necessary
- Handles read and write requests to physical addresses
- Supports requests that may span multiple pages
- Simulates access delay as specified in the configuration file
- The Memory module comprises approximately 20% of the overall project workload.
- Ensure proper implementation of the paging scheme.
- Handle multi-page operations correctly.
- Implement accurate simulation of memory access delays.
- Maintain proper synchronization for concurrent access from different modules.
The I/O Interface module simulates various input/output devices such as keyboards, mice, disks, monitors, and printers. It handles operations requested by the Kernel for specific processes, processing them one at a time in the order of arrival.
- Generic Interfaces
- STDIN Interfaces
- STDOUT Interfaces
- DialFS Interfaces
Each I/O Interface requires two parameters at startup:
- Name: A unique identifier for the interface within the system
- Configuration File: Contains specific settings for the interface
- Simplest type of interface
- Waits for a specified number of work units upon request
- Accepts instruction: IO_GEN_SLEEP
- Configuration properties: type, unit_work_time, ip_kernel, port_kernel
- Waits for user input via keyboard
- Stores input in memory at the specified physical address
- Accepts instruction: IO_STDIN_READ
- Configuration properties: type, ip_kernel, port_kernel, ip_memory, port_memory
- Reads from a physical memory address and displays the result
- Always consumes one unit of unit_work_time
- Accepts instruction: IO_STDOUT_WRITE
- Configuration properties: type, unit_work_time, ip_kernel, port_kernel, ip_memory, port_memory
- Most complex interface type
- Interacts with a file system (DialFS) implemented by the project group
- Always consumes one unit of unit_work_time
- Accepts instructions: IO_FS_CREATE, IO_FS_DELETE, IO_FS_TRUNCATE, IO_FS_WRITE, IO_FS_READ
- Configuration properties: type, unit_work_time, ip_kernel, port_kernel, ip_memory, port_memory, dialfs_path, dialfs_block_size, dialfs_block_count
DialFS is a simple implementation of a Contiguous Allocation File System, simulated using the following files:
- blocks.dat: Represents the file system blocks
- bitmap.dat: Bitmap indicating free and occupied blocks
- Metadata files: JSON files for each file in the FS, containing initial block and size information
- File Creation: Initially occupies one block, even for empty files
- Compaction: Regroups files to create contiguous free space when needed
- Truncation: Allows file size adjustment using IO_FS_TRUNCATE
- Ensure proper handling of different interface types and their specific instructions
- Implement accurate simulation of work unit delays
- For DialFS, ensure correct implementation of the bitmap-based block allocation
- Handle file system compaction when necessary
- Maintain proper synchronization for concurrent access from different processes
- Linux environment (can be run in a virtual machine)
- Git
- Go programming language
-
Set up the Linux environment:
- If using a VM, ensure it's properly configured
-
Install Go
-
Clone the project repository:
git clone https://github.com/FaustoOliva/SO-Panza_Confianza.git
-
Configure IP addresses:
cd /path/to/SO-Panza_Confianza/ejecutablesSH go run script_ip.go -es "ipIO" -cpu "ipCPU" -kernel "ipKERNEL" -memoria "ipMEMORIA"
Note: If running all modules locally, use "localhost" for all modules.
- KERNEL
go build -o kernel.exe kernel.go
./kernel.exe /path/to/SO-Panza_Confianza/kernel/KERNELconfigs/DESIRED_CONFIG.json
- CPU
go build -o cpu.exe cpu.go
./cpu.exe /path/to/SO-Panza_Confianza/cpu/CPUconfigs/DESIRED_CONFIG.json
- MEMORY
go build -o memoria.exe memoria.go
./memoria.exe /path/to/SO-Panza_Confianza/memoria/MEMconfigs/DESIRED_CONFIG.json
- I/O (run as needed)
go build -o entradasalida.exe entradasalida.go
./entradasalida.exe INTERFACE_NAME /path/to/SO-Panza_Confianza/entradasalida/ioConfigs/INTERFACE_NAME.json
For a complete list of available tests and their descriptions, please refer to the test documentation.
- Navigate to the test scripts folder:
cd /path/to/SO-Panza_Confianza/prueba/scripts_kernel
- Execute the desired test script:
./TEST_NAME.sh
Example: ./PRUEBA_PLANI.sh
- Ensure proper synchronization for concurrent access in all modules.
- Implement accurate simulation of delays and work units as specified in configuration files.
- For the DialFS, ensure correct implementation of the bitmap-based block allocation and handle file system compaction when necessary.
- Ensure all paths are correctly set according to your system's directory structure.
- Make sure all necessary permissions are granted for executing the scripts and binaries.
- It's recommended to run the modules in separate terminal windows for easier monitoring and debugging.
This project wouldn't be possible without the valuable contributions of the following individuals:
- Alan Garber (@AlanGarber)
- Gad Stamati (@GadStam)
- Gonzalo Vaserman (@gonzivaser)
- Franco Ysraelit (@FrancoYsrraelit)
Los quiero amigos :)