The PageAllocator class handles physical memory page allocation and provides the OS an interface for memory paging/mapping. The PageAllocator class is portable, making use of the SharpOS.ADC.Pager class to implement platform- specific paging mechanisms.
예제 #1
0
		public static PageAttributes GetPageAttributes (void* page, uint granularity,
								   PageAllocator.Errors* ret_err)
		{
			return Pager.GetPageAttributes (page, granularity, ret_err);
		}
예제 #2
0
파일: Pager.cs 프로젝트: sharpos/SharpOS
		public static PageAttributes GetPageAttributes (void* page, uint granularity,
								      PageAllocator.Errors* ret_err)
		{
			uint pde = 0, pte = 0;
			uint* table = null;

			if (granularity < 0 || granularity > 1) {
				*ret_err = PageAllocator.Errors.UnsupportedGranularity;
				return PageAttributes.None;
			}

			Diagnostics.Assert(ADC.Pager.GetPointerGranularity(page) == granularity,
				"X86.Pager.GetPageAttributes(): bad page pointer alignment!");

			PagePtrToTables(page, &pde, &pte);
			table = PageDirectory;

			if (granularity == 0)
				table = (uint*)(table[pde] & (uint)PageAttr.FrameMask);

			*ret_err = PageAllocator.Errors.Success;
			return GetAbstractPMA((PageAttr)(table[pde] &
					(uint)PageAttr.AttributeMask));
		}
예제 #3
0
파일: Pager.cs 프로젝트: sharpos/SharpOS
		public static PageAllocator.Errors Setup(uint totalMem, byte* pagemap, uint pagemapLen, PageAllocator.Errors* error)
		{
			if (pagemap == null ||
				pagemapLen < ComputeControlReq(totalMem)) {
				*error = PageAllocator.Errors.UnusablePageControlBuffer;
				return *error;
			}

			uint totalBytes = totalMem * 1024;	// more intuitive to think in bytes than in kibibytes

			PageDirectory = (uint*)pagemap;
			PageTables = (uint*)(((byte*)PageDirectory) + 4096);

			uint addr = 0;
			uint* table = (uint*)PageTables;

			// Page directory needs to span all 4 GBs
			// FIXME: What about PAE support might different implementation
			// uint totalPages = UInt32.MaxValue / 4096; // Each page spans of memory 4MB
			uint totalTables = 1024; // 1024 * 4MB = 4GB

			MemoryUtil.MemSet32(0, (uint)PageDirectory, 1024);

			for (int x = 0; x < totalTables; ++x) {
				bool needsDirectoryPresent = false;

				for (int i = 0; i < 1024; ++i) {
					uint val = (addr & (uint)PageAttr.FrameMask) |
						(uint)(PageAttr.ReadWrite);

					if (addr <= totalBytes) {
						val |= (uint)PageAttr.Present;
						needsDirectoryPresent = true;
					}

					table[i] = val;
					addr += 4096;
				}

				// top-level page directory (level-1)
				uint pageAddress = (uint)table & (uint)PageAttr.FrameMask;

				// Make direcory read/write enabled
				pageAddress |= (uint)PageAttr.ReadWrite;

				if (needsDirectoryPresent) {
					// Make directory present if its point to a physical memory already
					pageAddress |= (uint)PageAttr.Present;
				}

				PageDirectory[x] = pageAddress;

				table += 1024;	// 1024 x sizeof(int) = 4k
			}

			DMA.Setup((byte*)((uint)pagemap) + pagemapLen);

			*error = PageAllocator.Errors.Success;
			return *error;
		}
예제 #4
0
파일: Pager.cs 프로젝트: sharpos/SharpOS
		public static PageAllocator.Errors Enable(PageAllocator.Errors* error)
		{
			if (PageDirectory == null) {
				*error = PageAllocator.Errors.UnusablePageControlBuffer;
				return *error;
			}

			SetDirectory((uint)PageDirectory);

			*error = PageAllocator.Errors.Success;
			return *error;
		}
예제 #5
0
파일: Pager.cs 프로젝트: sharpos/SharpOS
		public static uint GetGranularitySize(uint granularity, PageAllocator.Errors* ret_err)
		{
			if (granularity < 0 || granularity > 1) {
				*ret_err = PageAllocator.Errors.UnsupportedGranularity;
				return 0;
			}

			*ret_err = PageAllocator.Errors.Success;

			switch (granularity) {
				case 0:
					return 4096;
				case 1:
					return 131072;
				default:
					*ret_err = PageAllocator.Errors.UnsupportedGranularity;
					return 0xFFFFFFFF;
			}
		}