/// <summary> /// /// </summary> /// <param name="virtualMemSizeIn"></param> public MemoryManager(uint virtualMemSizeIn) { // // Find a size for addressableMemory that is on a page boundary // virtualMemSize = CPU.UtilRoundToBoundary(virtualMemSizeIn, CPU.pageSize); // // Size of memory must be a factor of CPU.pageSize // This was asserted when the CPU initialized memory // uint physicalpages = (uint)(CPU.physicalMemory.Length / CPU.pageSize); uint addressablepages = (uint)(virtualMemSize / CPU.pageSize); _pageTable = new ArrayList((int)addressablepages); // Delete all our Swap Files foreach (string f in Directory.GetFiles(".", "*.xml")) { File.Delete(f); } // For all off addressable memory... // Make the pages in physical and the pages that aren't in physical for (uint i = 0; i < virtualMemSize; i += CPU.pageSize) { // Mark the Pages that are in physical memory as "false" or "not free" MemoryPage p; if (i < CPU.physicalMemory.Length) { p = new MemoryPage(i, true); freePhysicalPages[(int)(i / CPU.pageSize)] = false; } else { p = new MemoryPage(i, false); } _pageTable.Add(p); } // // Cordon off some shared memory regions...these are setting the AppSettings // uint SharedRegionsSize = uint.Parse(EntryPoint.Configuration["SharedMemoryRegionSize"]); uint SharedRegions = uint.Parse(EntryPoint.Configuration["NumOfSharedMemoryRegions"]); if (SharedRegions > 0 && SharedRegionsSize > 0) { uint TotalPagesNeeded = (uint)(SharedRegions * SharedRegionsSize / CPU.pageSize); uint pagesPerRegion = TotalPagesNeeded / SharedRegions; // ForExample: // I need 2 regions // 64 bytes needed for each // 4 pages each // 8 total pages needed // Because I pre-allocate shared memory I'll have the luxury of contigous pages of memory. // I'll exploit this hack in MapSharedMemoryToProcess foreach (MemoryPage page in _pageTable) { // Do we still need pages? if (TotalPagesNeeded > 0) { // If this page is assigned to the OS, take it if (page.SharedMemoryRegion == 0) { // Now assign it to us page.SharedMemoryRegion = SharedRegions; TotalPagesNeeded--; if (TotalPagesNeeded % pagesPerRegion == 0) { SharedRegions--; } } } else //We have all we need { break; } } } }
/// <summary> /// Helper method to translate # of bytes to # of Memory Pages /// </summary> /// <param name="bytes">bytes to translate</param> /// <returns>number of pages</returns> public static uint BytesToPages(uint bytes) { return(CPU.UtilRoundToBoundary(bytes, CPU.pageSize) / CPU.pageSize); //return ((uint)(bytes / CPU.pageSize) + (uint)(bytes % CPU.pageSize)); }
/// <summary> /// Gets a 4 byte unsigned integer (typically an opCode param) from memory /// </summary> /// <param name="processid">The calling processid</param> /// <param name="processIndex">The address in memory from the Process's point of view</param> /// <returns></returns> public uint getUIntFrom(uint processid, uint processIndex) { return(CPU.BytesToUInt(getBytesFrom(processid, processIndex, 4))); }
/// <summary> /// Sets a 4 byte unsigned integer (typically an opCode param) to memory /// </summary> /// <param name="processid">The calling processid</param> /// <param name="processIndex">The address in memory from the Process's point of view</param> /// <param name="avalue">The new value</param> public void setUIntAt(uint processid, uint processIndex, uint avalue) { setBytesAt(processid, processIndex, CPU.UIntToBytes(avalue)); }
static void Main(string[] args) { var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json"); Configuration = builder.Build(); OS theOS = null; uint bytesOfVirtualMemory = 0; uint bytesOfPhysicalMemory = 0; PrintHeader(); if (args.Length < 2) { PrintInstructions(); } else { //try { // Total addressable (virtual) memory taken from the command line bytesOfVirtualMemory = uint.Parse(args[0]); bytesOfPhysicalMemory = uint.Parse(Configuration["PhysicalMemory"]); // Setup static physical memory CPU.initPhysicalMemory(bytesOfPhysicalMemory); // Create the OS and Memory Manager with Virtual Memory theOS = new OS(bytesOfVirtualMemory); // Let the CPU know about the OS CPU.theOS = theOS; Console.WriteLine("CPU has {0} bytes of physical memory", CPU.physicalMemory.Length); Console.WriteLine("OS has {0} bytes of virtual (addressable) memory", theOS.memoryMgr.virtualMemSize); // For each file on the command line, load the program and create a process for (int i = 1; i < args.Length; i++) { if (File.Exists(args[i])) { Program p = Program.LoadProgram(args[i]); Process rp = theOS.createProcess(p, uint.Parse(Configuration["ProcessMemory"])); Console.WriteLine("Process id {0} has {1} bytes of process memory and {2} bytes of heap", rp.PCB.pid, Configuration["ProcessMemory"], rp.PCB.heapAddrEnd - rp.PCB.heapAddrStart); p.DumpProgram(); } } // Start executing! theOS.execute(); } //catch (Exception e) { //PrintInstructions(); //Console.WriteLine(e.ToString()); } // Pause Console.WriteLine("OS execution complete. Press Enter to continue..."); Console.ReadLine(); } }