General Info | |
Interface: MemManager_i386 Files: memmanager_i386.h Last change: 08/06/2005 Author: Luiz Henrique Shigunov |
Description
Structures |
Functions | |
0x00 - AllocPages - Allocate logical pages 0x01 - AllocPhysPages - Allocate physical pages 0x02 - Block - Block memory pages 0x03 - Catch - Catch an exception 0x04 - CreateDescriptor - Create a system descriptor 0x05 - CreatePGD - Create a memory map 0x06 - DestroyDescriptor - Destroy a system descriptor |
0x07 - FreeException - Free an exception 0x08 - FreePages - Free logical pages 0x09 - FreePhysPages - Free physical pages 0x0a - MapPhysPages - Map physical pages 0x0b - SetPagesProp - Set pages properties 0x0c - Unblock - Unblock memory pages |
This page describes the MemManager_i386 interface which provides functions to manage system logical memory, system physical memory, the page table, the GDT and memory exceptions.
Logical memory management is divided in logical memory page management and variable size memory management.
System modules can allocate, free and set logical/physical page properties. They can block some logical pages (don't allowing them to be without mapping) and unblock.
The memory manager provides functions to map unavailable physical pages (video memory, IO, etc).
ModulOS uses a not segmented memory model. Two code segments (one for system modules and another for user tasks) and one data segment used by system modules and by user tasks exist. All these segments have 4 GB of size, that is, all memory address space.
Each task has a memory mapping. The first 3,5 GB of logical memory is available for tasks and the rest 512 MB is reserved for system modules.
So, at each task switch a memory mapping is loaded. But, for system call the mapping is the same.
typedef struct { unsigned short limit15; /* the first 16 bits of the segment limit */ unsigned short base15; /* the first 16 bits of the segment base */ unsigned int base23 : 8, /* more 8 bits of the segment base */ type : 4, /* type of segment */ s : 1, /* system segment */ dpl : 2, /* privilege level */ p : 1, /* present segment */ limit19 : 4, /* the last 4 bits of the limit */ avl : 1, /* available */ reserved: 1, /* reserved, must be 0 */ db : 1, /* default data size */ g : 1, /* limit granulaty */ base31 : 8; /* the last 8 bits of the segment base */ } MemManager_i386_SegDescriptor;
void *MemManager_i386_AllocPages(unsigned int n, int prop);
This function allocates n logical pages with properties prop.
prop must be 0 or the sum of:
If prop has MemManager_i386_ALLOC_PHYS, physical pages will be allocated too and will be mapped in the logical pages allocated.
Physical pages, if allocated, won't have any special properties (blocked, continuous, etc).
Property MemManager_i386_CLEAR_PAGES only makes sense if physical pages are allocated.
Use the macros IS_PTR_ERROR and PTR_TO_ERROR to know whether an error occurred and to get the error.
unsigned int MemManager_i386_AllocPhysPages(unsigned int n, int prop);
This function allocates n continuous physical pages with properties prop.
prop must be 0 or the sum of:
Blocked physical pages don't get out of physical memory (for virtual memory).
Properties 0x02-0x08 are used mainly by old devices.
Although the type of the returned value is not a pointer, the same error code scheme is used.
So, use the macros IS_PTR_ERROR and PTR_TO_ERROR to know whether an error occurred and to get the error.
int MemManager_i386_Block(void *ptr, unsigned int size);
This function blocks all pages between ptr and ptr + size.
size is the size in bytes.
If a page is blocked n times, it should be unblocked n times too.
int MemManager_i386_Catch(void *start, void *end, void *function, int prop);
This function registers function to handle page fault exceptions (not present or page protection fault).
Two types of page faults exist. One based on who caused the exception (executable code that caused the exception don't matter the processor mode) and another based on the processor mode.
The type based on who caused is usually used to catch errors when executing system modules code (try to access an invalid memory area, for instance).
But the type based on the processor mode is used to catch programs errors (try to execute system code, for instance) and it happens whenever the processor is in user mode don't matter the address where the exception ocurred.
When a page fault occurs the handlers based on the processor mode are called. If no handler handles the exception then the handlers based on who caused are called.
start and size are addresses and are used if prop doesn't has MemManager_i386_EX_USER_MODE.
The thread that executes the handler may be destroyable. If this is a problem functions Undestroyable e Destroyable from the TaskManager interface must be used.
prop must be 0 or the sum of:
If prop doesn't has MemManager_i386_EX_USER_MODE, the handler is called when the code address of who caused the exception is between start-end, including.
If prop doesn't has MemManager_i386_EX_RETURN, function must have this syntax:
int my_handler(void *address, IntManager_i386_ExRegs *regs)
Where address is the address where the exception occurred and regs is the thread's registers. EIP regs's member is the code address where the exception occurred and ErrorCode has this format:
Bit | Description |
---|---|
0 | 0 - Page not present fault; 1 - Protection violation fault. |
1 | 0 - Read attempt; 1 - Write attempt. |
2 | 0 - Processor was executing in supervisor/system mode; 1 - Processor was executing in user mode. |
Upon returning the handler says what to do:
Returning E_HANDLED_INT says that others handlers in the list must not be called, but returning E_UNHANDLED_INT says to call them.
int MemManager_i386_CreateDescriptor(MemManager_i386_SegDescriptor descriptor, unsigned short *selector);
This function puts descriptor in the GDT and returns in selector the selector number allocated.
The descriptor must conform to SegDescriptor.
unsigned int MemManager_i386_CreatePGD(void);
This function creates a memory mapping.
When a PGD is created, all system PDEs are initialized and the rest is filled with zeros.
To free a PGD just call FreePhysPages with size = 1.
Although the type of the returned value is not a pointer, the same error code scheme is used.
So, use the macros IS_PTR_ERROR and PTR_TO_ERROR to know whether an error occurred and to get the error.
int MemManager_i386_DestroyDescriptor(unsigned int selector);
This function destroys the descriptor identified by selector.
int MemManager_i386_FreeException(void *start, void *function, int prop);
This function removes function from handling page exceptions occured in start.
prop must be 0 or the sum of:
int MemManager_i386_FreePages(void *pages, unsigned int n, int prop);
This function frees n logical pages from pages.
prop must be 0 or the sum of:
int MemManager_i386_FreePhysPages(unsigned int pages, unsigned int n);
This function frees n physical pages from pages. For instance: pages could be 0, 0x1000, 0x2000, 0x3000, etc.
void *MemManager_i386_MapPhysPages(void *to, unsigned int start, unsigned int n, int prop);
This function maps n physical pages from start in logical memory to, setting logical pages properties to prop.
start must be the physical page address. For instance: 0, 0x1000, 0x2000, 0x3000, etc.
If prop has MemManager_i386_ALLOC_PAGES, to isn't used.
If prop doesn't has MemManager_i386_ALLOC_PAGES, to must be inside system memory area and be allocated using AllocPages.
prop must be 0 or the sum of:
Use the macros IS_PTR_ERROR and PTR_TO_ERROR to know whether an error occurred and to get the error.
int MemManager_i386_SetPagesProp(void *start, unsigned int n, int prop);
This function sets the first n logical pages properties from address start to prop.
Logical pages must have been allocated using AllocPages.
prop must be 0 or the sum of:
int MemManager_i386_Unblock(void *ptr, unsigned int size);
This function unblocks all pages between address ptr and ptr + size.
size is the size in bytes.
If a page is blocked n times, it should be unblocked n times too.