ModStart是如何计算的,看不懂

学操作系统,与毛德操老师一起情景分析

版主: casualfish

ModStart是如何计算的,看不懂

帖子qtdszws 于 2010-01-08 10:53

KiRosFrldrLpbToNtLpb(IN PROS_LOADER_PARAMETER_BLOCK RosLoaderBlock,
IN PLOADER_PARAMETER_BLOCK *NtLoaderBlock)
{
...
/* Loop boot driver list */
for (i = 0; i < RosLoaderBlock->ModsCount; i++)
{
/* Get the ROS loader entry */
RosEntry = &RosLoaderBlock->ModsAddr[i];
DriverName = (PCHAR)RosEntry->String;
ModStart = (PVOID)RosEntry->ModStart;
ModSize = RosEntry->ModEnd - (ULONG_PTR)ModStart;

/* Check if this is any of the NLS files */
if (!_stricmp(DriverName, "ansi.nls"))
{
/* ANSI Code page */
ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000));
LoaderBlock->NlsData->AnsiCodePageData = ModStart;

/* Create an MD for it */
MdEntry = KiRosGetMdFromArray();
MdEntry->MemoryType = LoaderNlsData;
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
MdEntry->PageCount = (ModSize + PAGE_SIZE - 1)>> PAGE_SHIFT;
InsertTailList(&LoaderBlock->MemoryDescriptorListHead,
&MdEntry->ListEntry);
continue;
}
...
}

这里ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000));

MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
这两行到底是如何计算的?看不懂?(ModStart初值应该在0x80000000~0x80000000+8M之间)
qtdszws
 
帖子: 20
注册: 2009-10-20 14:54

Re: ModStart是如何计算的,看不懂

帖子welfear 于 2010-01-08 12:13

这句是对nls的重定向,可能是对ansi对特殊处理,猜测。
ModStart = (PVOID)((ULONG_PTR)ModStart + (KSEG0_BASE - 0x200000));

这句是得到开始的物理页,我记得NT映射内核空间地址到物理地址用了简单的线性关系,
所以去掉最高位和页的整数倍就是页序号。
MdEntry->BasePage = ((ULONG_PTR)ModStart &~ KSEG0_BASE) >> PAGE_SHIFT;
技法无高下 功力有深浅
welfear
 
帖子: 534
注册: 2008-12-20 12:19

Re: ModStart是如何计算的,看不懂

帖子qtdszws 于 2010-01-09 19:56

现在明白了

对于PE模块,ModStart是0x80000000+x
对于其他模块(nls,hive),ModStart是模块加载的物理地址4M+x
qtdszws
 
帖子: 20
注册: 2009-10-20 14:54


回到 情景分析讨论版

在线用户

正在浏览此版面的用户:没有注册用户 和 1 位游客