📄 pagemgr.c
字号:
//返回值:
// 假如成功,返回有效内存页地址;否则返回NULL
//功能描述:
// 分配一内存页
//引用:
// ********************************************************************
void * Page_Alloc( BOOL bUpdateFreePages )
{
void * lp = NULL;
UINT uiSave;
LockIRQSave( &uiSave );
// 空闲页表是否为空?
if( (bUpdateFreePages && uiFreePages) ||
(bUpdateFreePages == FALSE && lpFreePageList) )
//if( lpFreePageList )
{ // 不为空
LPSEGMENTINFO lpSegInfo;
//lp = lpFreePageList;
lp = Page_RemoveFromFreeList( bUpdateFreePages );
// 得到该页所在的内存段
lpSegInfo = Page_GetSeg( lp );
// ASSERT( lpSegInfo );
// 将该页在内存段相应的位设为占用状态
lpSegInfo->lpbFreeMemMap[GET_INDEX( lpSegInfo, lp )] = FLAG_USED;
}
UnlockIRQRestore( &uiSave );
// 如果有CACHE功能,将其转化为CACHE指针
return lp ? (void*)UNCACHE_TO_CACHE( lp ) : NULL;
}
// ********************************************************************
//声明:BOOL Page_Free( LPVOID lpvMemAdr )
//参数:
// IN lpvMemAdr - 需要释放的页
//
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 与Page_Alloc相对应,释放一个页内存。
//引用:
// ********************************************************************
#define DEBUG_Page_Free 0
BOOL Page_Free( LPVOID lpvMemAdr )
{
LPSEGMENTINFO lpSegInfo;
// ASSERT( lpvMemAdr );
// 如果有CACHE功能,将其转化为UNCACHE指针
lpvMemAdr = (LPVOID)CACHE_TO_UNCACHE( lpvMemAdr );
// 得到该内存所在的页
lpSegInfo = Page_GetSeg( lpvMemAdr );
if( lpSegInfo )
{
UINT uiSave;
int index;
// 得到该页在内存段的索引号
index = GET_INDEX( lpSegInfo, lpvMemAdr );
LockIRQSave( &uiSave );
//ASSERT( lpSegInfo->lpbFreeMemMap[index] );
// 该内存页的引用计数是否为0
if( lpSegInfo->lpbFreeMemMap[index] )
{
if( --lpSegInfo->lpbFreeMemMap[index] == 0 )
Page_AddToFreeList( lpvMemAdr ); //是,将其加入到空闲链表
}
else
{
ERRORMSG( DEBUG_Page_Free, ( "error in Page_Free: lpvMemAdr=0x%x.\r\n", lpvMemAdr ) );
}
UnlockIRQRestore( &uiSave );
}
else
{ // 不一定是错,有可能是代码页,也通过该函数
;//RETAILMSG( 1, ( "failure error at Page_Free(0x%x): lpSegInfo = NULL!.\r\n", lpvMemAdr ) );
}
return TRUE;
}
// ********************************************************************
//声明:BOOL Page_Get( LPVOID * lppAdr, DWORD dwPages )
//参数:
// IN lppAdr - 指向用于接收页地址的指针数组,该数组的大小应该等于dwPages -> lppAdr[dwPages]
// IN dwPages - 需要的页数
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 得到一些页内存
//引用:
// ********************************************************************
BOOL Page_Get( LPVOID * lppAdr, DWORD dwPages )
{
// 先锁住需要的页
if( Page_Lock( dwPages ) )
{ //锁住成功
while( dwPages-- )
{ //得到每个页
*lppAdr++ = Page_Alloc( FALSE );
}
return TRUE;
}
return FALSE;
}
// ********************************************************************
//声明:BOOL Page_Release( LPVOID * lppAdr, DWORD dwPages )
//参数:
// IN lppAdr - 指向用于保存有页地址的指针数组,该数组的大小应该等于dwPages -> lppAdr[dwPages]
// IN dwPages - 需要释放的页数
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 与Page_Get对应,释放一些页内存
//引用:
// ********************************************************************
BOOL Page_Release( LPVOID * lppAdr, DWORD dwPages )
{
while( dwPages-- )
{
//ASSERT( *lppAdr );
Page_Free( *lppAdr );
lppAdr++;
}
return TRUE;
}
// ********************************************************************
//声明:LPVOID Page_GetContiguous( DWORD dwPages, DWORD dwAlignmentMask )
//参数:
// IN dwPages - 需要分配的页数
// IN dwAlignmentMask - 页开始地址对齐mask
//返回值:
// 假如成功,返回非NULL的内存地址;否则返回NULL
//功能描述:
// 得到连续的页内存
//引用:
// ********************************************************************
LPVOID Page_GetContiguous( DWORD dwPages, DWORD dwAlignmentMask )
{
LPVOID lpvRet = NULL;
// 锁住需要的页
if( Page_Lock( dwPages ) )
{ //
LPSEGMENTINFO lpSegInfo = memInfo.lpSectionInfo;
LPSEGMENTINFO lpSegInfoEnd = lpSegInfo + memInfo.dwSections;
// 遍历所有的内存段,得到一块连续的内存
for( ; lpSegInfo < lpSegInfoEnd; lpSegInfo++ )
{
LPBYTE lpbMemMapS = lpSegInfo->lpbFreeMemMap;
LPBYTE lpbMemMapE = lpbMemMapS + lpSegInfo->dwTotalPages - dwPages;
LPBYTE lpbPageStart = lpSegInfo->lpbFreePageStart;
DWORD dwIndexBegin = 0;
// 查找当前内存段
for( ; lpbMemMapS <= lpbMemMapE; lpbMemMapS++, dwIndexBegin++, lpbPageStart += PAGE_SIZE )
{ // 该页是否是空闲的或是否对齐地址
if( *lpbMemMapS ||
( (DWORD)lpbPageStart & dwAlignmentMask )
)
{ // 占用或没有对齐
continue;
}
else
{ // 符合条件,从该页向下遍历其它需要的内存页
LPBYTE lpbFirst = lpbMemMapS;
LPBYTE lpbEnd = lpbFirst + dwPages;
DWORD dwCurIndex = dwIndexBegin;
for( ; lpbFirst < lpbEnd; lpbFirst++, dwCurIndex++ )
{ // 是否是空闲 或 分配成功?
if( *lpbFirst ||
Page_GetSpecific( lpSegInfo, dwCurIndex ) == FALSE )
{ // 不成功,释放之前已分配的内存页
DWORD n = dwIndexBegin;
for( ; n < dwCurIndex; n++ )
{
Page_ReleaseSpecific( lpSegInfo, n );
}
// 重新设定遍历开始位置
lpbMemMapS = lpbFirst + 1;
dwIndexBegin = dwCurIndex + 1;
lpbPageStart = lpSegInfo->lpbFreePageStart + dwIndexBegin * PAGE_SIZE;
break;
}
}
if( lpbFirst == lpbEnd )
{ // 已经得到所有需要的内存页 //i get all page needed
lpvRet = lpbPageStart;
goto _RET;
}
}
}
// 不成功,解锁
Page_Unlock( dwPages );
}
}
_RET:
// 如果有CACHE功能,将其转化为CACHE指针
return lpvRet ? (LPVOID)UNCACHE_TO_CACHE(lpvRet) : NULL;
}
// ********************************************************************
//声明:BOOL Page_ReleaseContiguous( LPVOID lpAdr, DWORD dwPages )
//参数:
// IN lpAdr - 需要释放的页开始地址
// IN dwPages - 需要释放的页数
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 与Page_GetContiguous对应,释放连续的页内存
//引用:
// ********************************************************************
BOOL Page_ReleaseContiguous( LPVOID lpAdr, DWORD dwPages )
{
for( ; dwPages; dwPages-- )
{
//ASSERT( lpAdr );
Page_Free( lpAdr );
// 下一页地址
lpAdr = (LPVOID)( (DWORD)lpAdr + PAGE_SIZE );
}
return TRUE;
}
// ********************************************************************
//声明:BOOL Page_InitSysPages( void )
//参数:
// 无
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 当内核启动时,初始化系统内存页,在调用该函数之前lpbSysMainMem,ulSysMainMemLength必须先初始化
//引用:
// ********************************************************************
BOOL Page_InitSysPages( void )
{
extern void OEM_WriteDebugString( LPCTSTR lpszStr );
int k, iSegNum;
MEM_SEGMENT seg[MAX_SEGMENTS];
char buf[16];
// 输出调试信息 - begin
OEM_WriteDebugString( "Page_InitSysPages:lpbSysMainMem=0x" );
itoa( (DWORD)lpbSysMainMem, buf, 16 );
OEM_WriteDebugString( buf );
OEM_WriteDebugString( ",ulSysMainMemLength=" );
itoa( (DWORD)ulSysMainMemLength, buf, 10 );
OEM_WriteDebugString( buf );
OEM_WriteDebugString( "\r\n" );
// - end
// 如果带MMU,先刷新CACHE
#ifdef VIRTUAL_MEM
FlushCacheAndClearTLB();
#endif
// 初始化句柄基本地址
dwHandleBase = (DWORD)lpbSysMainMem & 0xE0000000;
lpbSysMainMemEnd = lpbSysMainMem + ulSysMainMemLength;
//初始化memInfo 信息
memInfo.lpbMainMemStart = (LPBYTE)CACHE_TO_UNCACHE( lpbSysMainMem );
memInfo.lpbMainMemEnd = memInfo.lpbMainMemStart + ulSysMainMemLength;
memInfo.lpbMainMemFreeStart = memInfo.lpbMainMemStart;
memInfo.dwMainMemFreeSize = ulSysMainMemLength;
//建立第一个内存段结构(用主内存)
memInfo.lpSectionInfo = (LPSEGMENTINFO)ALIGN_DWORD( (DWORD)memInfo.lpbMainMemFreeStart );
//初始化第一个内存段
seg[0].lpbStart = (LPBYTE)( memInfo.lpSectionInfo + MAX_SEGMENTS );
seg[0].dwSize = memInfo.dwMainMemFreeSize - ( seg[0].lpbStart - memInfo.lpbMainMemFreeStart );
//得到系统其它附加内存段数
iSegNum = OEM_EnumExtensionDRAM( seg+1, MAX_SEGMENTS-1 );
iSegNum += 1; // 总的内存段数
//初始化每一个内存段
for( k = 0; k < iSegNum; k++ )
{
LPBYTE lpbPageStart, lpbPageEnd;
DWORD dwPages;
memInfo.lpSectionInfo[k].lpbMemStart = seg[0].lpbStart;
memInfo.lpSectionInfo[k].dwMemSize = seg[0].dwSize;
memInfo.lpSectionInfo[k].lpbFreeMemMap = memInfo.lpSectionInfo[k].lpbMemStart;//
// 该段页开始位置
lpbPageStart = (LPBYTE)ALIGN_PAGE_UP( (DWORD)memInfo.lpSectionInfo[k].lpbMemStart );
// 该段页结束位置
lpbPageEnd = (LPBYTE)ALIGN_PAGE_DOWN( (DWORD)(memInfo.lpSectionInfo[k].lpbMemStart + memInfo.lpSectionInfo[k].dwMemSize) );//.lpbMemStart +
// 该段页数
dwPages = (lpbPageEnd - lpbPageStart) / PAGE_SIZE;
// 该段空闲页开始位置
memInfo.lpSectionInfo[k].lpbFreePageStart = (LPBYTE)ALIGN_PAGE_UP( (DWORD)(memInfo.lpSectionInfo[k].lpbFreeMemMap + dwPages) );
// 该段空闲页结束位置
memInfo.lpSectionInfo[k].lpbFreePageEnd = lpbPageEnd;
// 该段总的可用页数
memInfo.lpSectionInfo[k].dwTotalPages = (memInfo.lpSectionInfo[k].lpbFreePageEnd - memInfo.lpSectionInfo[k].lpbFreePageStart) / PAGE_SIZE;
// 将页属性设为空闲状态
memset( memInfo.lpSectionInfo[k].lpbFreeMemMap, 0, memInfo.lpSectionInfo[k].dwTotalPages );
}
memInfo.dwSections = iSegNum;
// 将所有内存段的空闲页加入空闲链表。now , add free pages to pagelist
for( k = 0; k < iSegNum ; k++ )
{
LPBYTE lpbPageStart = memInfo.lpSectionInfo[k].lpbFreePageStart;
LPBYTE lpbPageEnd = memInfo.lpSectionInfo[k].lpbFreePageEnd;
while( lpbPageStart < lpbPageEnd )
{
Page_AddToFreeList( (LPPAGELIST)lpbPageStart );
lpbPageStart += PAGE_SIZE;
}
}
//
return TRUE;
}
// ********************************************************************
//声明:BOOL _InitSysMem( void )
//参数:
// 无
//返回值:
// 假如成功,返回TRUE;否则返回FALSE
//功能描述:
// 当内核启动时,初始化系统内存页,在调用该函数之前lpbSysMainMem,ulSysMainMemLength必须先初始化
//引用:
// ********************************************************************
BOOL _InitSysMem( void )
{
return Page_InitSysPages();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -