📄 pm2_paging.c
字号:
RestoreEflags(ulFlags);
return ulPageAddr;
}
/************************************************************
*************************************************************
** Function Name: iPm2DoPageFault
** Author: x.cheng
**
** Comment:
** 缺页异常处理
**
**
**
** List of parameters:
** ulVirtualAddr - 引发缺页的线性地址
**
** Return value:
** 0 - ok
** other - error
**
** Revisions:
** 0.01-处理很简单,如果发生缺页了,我就申请一个页
*************************************************************
*************************************************************/
int iPm2DoPageFault(unsigned long ulVirtualAddr)
{
unsigned long ulPageFrame;
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("page fault: linear address %p\n", ulVirtualAddr);
#endif
#endif
if ( NULL == ulVirtualAddr ) {
kprintf("NULL address is forbidden.\n");
return (-1);
}
if ( NULL == (ulPageFrame = ulPm2GetOneFreePage()) ) {
kprintf("out of memory...\n");
return (-1);
}
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("%s(): free pfn= %p, for %p\n", __FUNCTION__, ulPageFrame, ulVirtualAddr);
#endif
#endif
//map page with correct attributes
if ( ulVirtualAddr < KERNEL_VIRTUAL_START ) {
ulPm2MapPageToVirtualAddress(ulPageFrame, ulVirtualAddr, P_PRESENT | P_WRITE | P_USER);
} else {
ulPm2MapPageToVirtualAddress(ulPageFrame, ulVirtualAddr, P_PRESENT | P_WRITE);
}
//ZeroPage((void *)ulPageFrame);
ZeroPage((void *)PHYSICAL(ulPageFrame));
return 0;
}
/************************************************************
*************************************************************
** Function Name: iPm2DoPageWriteProtect
** Author: x.cheng
**
** Comment:
** 页写保护异常处理
**
**
**
** List of parameters:
** ulVirtualAddr - 引发缺页的线性地址
**
** Return value:
** 0 - ok
** other - error
**
** Revisions:
**
*************************************************************/
int iPm2DoPageWriteProtect(unsigned long ulLinearAddr)
{
panic("\npage write protect: linear address %p", ulLinearAddr);
return 0;
}
/************************************************************
*************************************************************
** Function Name: vPm2PageInit
** Author: x.cheng
**
** Comment:
** Initial pagine memory...
** List of parameters:
** no
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
void vPm2PageInit(unsigned long ulMemoryEnd)
{
unsigned long ulAddress;
unsigned char* pucBitmap;
DmaSetupMemoryEnd( ulMemoryEnd );
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("Free pageable memory in: [%x]<->[%x]\n", DMA_MEMORY_END, ulMemoryEnd+KERNEL_VIRTUAL_START);
#endif
#endif
g_pucMemoryBitmapEnd = g_pucMemoryBitmapStart + (ulMemoryEnd >> 12);
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("page vector in: [%p]<->[%p]\n", g_pucMemoryBitmapStart, g_pucMemoryBitmapEnd);
#endif
#endif
vDbgDummy();
pucBitmap = g_pucMemoryBitmapStart;
while(pucBitmap<g_pucMemoryBitmapEnd) {
*pucBitmap = PAGE_USED;
pucBitmap++;
}
g_pucMemoryPageableStart = g_pucMemoryBitmapStart+( (DMA_MEMORY_END-KERNEL_VIRTUAL_START) >> 12 );
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("pagable memory in: [%p]<->[%p], vector in [%p<->[%p]\n", VECTOR_TO_LINEAR_ADDRESS(g_pucMemoryPageableStart), VECTOR_TO_LINEAR_ADDRESS(g_pucMemoryBitmapEnd),
g_pucMemoryPageableStart, g_pucMemoryBitmapEnd);
#endif
#endif
pucBitmap = g_pucMemoryPageableStart;
while(pucBitmap<g_pucMemoryBitmapEnd) {
*pucBitmap = 0;
pucBitmap++;
}
*pulAddressToPde( 0 ) = NULL; //unmap the first identical-map pages.
*pulAddressToPde( 0x400000 ) = NULL; //unmap the second identical-map pages.
//in head.asm, we map the first 8M to 0xc0000000-0xc08000000,
//here, we map the remainder, if we have......
if ( ulMemoryEnd > 8*1024*1024 ) {
for( ulAddress = 0xc0800000; ulAddress < (ulMemoryEnd+KERNEL_VIRTUAL_START); ulAddress += PAGE_SIZE )
ulPm2MapPageToVirtualAddress( ulAddress-KERNEL_VIRTUAL_START, ulAddress, P_PRESENT | P_WRITE | P_USER );
}
vDbgDummy();
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
kprintf("kernel text section in: [%p]<->[%p]\n", &KernelTextSectionStart_, &KernelTextSectionEnd_);
#endif
#endif
// Initialize kernel code section in read-only mode.
for( ulAddress = (unsigned long)&KernelTextSectionStart_; ulAddress < (unsigned long)&KernelTextSectionEnd_; ulAddress += PAGE_SIZE )
if( *pulAddressToPde(ulAddress) )
*pulAddressToPte( ulAddress ) &= ~P_WRITE;
/* //等完成了系统调用再加上去!
// Map only the exit point address available for users.
*pulAddressToPde( (unsigned long)&_Task_Exit_Point ) |= P_USER;
*pulAddressToPte( (unsigned long)&_Task_Exit_Point ) |= P_USER;
*/
/********************************************
* 固定内存的映射工作
********************************************/
// Map part of physical memory into the kernel address space. only first 16MB
for( ulAddress = KERNEL_PHYS_MEM_START; ulAddress < KERNEL_PHYS_MEM_END; ulAddress += PAGE_SIZE )
ulPm2MapPageToVirtualAddress( ulAddress-KERNEL_PHYS_MEM_START, ulAddress, P_PRESENT | P_WRITE | P_NOCACHE );
// Initialize temporary memory area.
for( ulAddress = KERNEL_TEMP_START_ADDRESS; ulAddress < KERNEL_TEMP_END_ADDRESS; ulAddress += PAGE_SIZE )
if( *pulAddressToPde(ulAddress) )
*pulAddressToPde(ulAddress) = NULL;
#ifdef _DEBUG__
#ifdef _DEBUG_PAGING_
Pm2ShowPageStatus();
#endif
#endif
FlushTlbAll();
vDbgDummy();
g_stGdtr.uiLimit = GDTE_MAX_SIZE*GDT_ENTRY_SIZE-1;
g_stGdtr.ulBase = (unsigned long)astGDT;
// Load info into GDTR //
__asm__ __volatile__ ("lgdtl (%0)" : : "r"(&g_stGdtr));
/* 在这之后不能调用显示函数,因为没有设置好显示内存*/
UpdateSegmentRegs();
}
/************************************************************
*************************************************************
** Function Name: Pm2ShowPageStatus
** Author: x.cheng
**
** Comment:
** 显示页表页目录状态...
**
** List of parameters:
** no
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
void Pm2ShowPageStatus( void )
{
int i, j, k, iFree=0;
unsigned long *pulPageTable;
unsigned char* pucBitmap;
pucBitmap = g_pucMemoryPageableStart;
while(pucBitmap<g_pucMemoryBitmapEnd) {
if( *pucBitmap == 0 )
iFree++;
pucBitmap++;
}
kprintf("system PDBR = %p\n", aulPageDir);
kprintf("%d pages free ( of %d )\n", iFree, g_pucMemoryBitmapEnd-g_pucMemoryBitmapStart);
vDbgDummy();
/* aulPageDir defined in system.h, but referenced in k_init.asm */
for (i=0; i<1024; i++) {
if ( 1 & aulPageDir[i] ) {
unsigned long ulAddress;
ulAddress = 0xfffff000&aulPageDir[i];
ulAddress += KERNEL_VIRTUAL_START;
pulPageTable = (unsigned long *)ulAddress;
// kprintf("pulPageTable= %p\n", pulPageTable);
for (j=k=0; j<1024; j++){
if (pulPageTable[j] & 1)
k++;
}
/*打印有效页目录项和对应的页表中有效的页表项 */
kprintf("\tPageDir[ %d] uses %d pages\n", i, k);
vDbgDummy();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -