ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:31.18KB ,
资源ID:18943741      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/18943741.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ntldr内存初始化分配操作和相关函数分析Word格式文档下载.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ntldr内存初始化分配操作和相关函数分析Word格式文档下载.docx

1、Routine Description:Arguments:Return Value:-*/ ULONG BAddr, EAddr, round; E820Frame Frame; / / Initialize the first entry in the list to zero (end-of-list) MemoryDescriptorList-BlockSize = 0;BlockBase = 0; / 调用Init15E820()函数,此时只是为了测试调用该函数是否成功 Frame.Key = 0; Frame.Size = sizeof (Frame.Descriptor); In

2、t15E820 (&Frame); if (Frame.ErrorFlag | Frame.Size sizeof (Frame.Descriptor) return FALSE; / 这里才是真正的获取内存块 do / 假定和限制 / BIOS返回那些描述大块内存的地址范围,随后是ISA/PCI内存;/ BIOS不返回被用作PCI设备,ISA可选ROM,以及ISA plus&play卡的内存映象,这是因为OS有相应的/ 机制可以检测到它们;/ BIOS返回芯片定义的地址空洞,这些地址作为保留不会被设备使用;/ 被定义的大块内存被映射到IO设备的地址范围作为保留地址将会被返回;/ 系统BIOS

3、的所有事件将会被作为保留内存返回,这包括低于1M的内存,在16M(如果存在) / 处的内存,以及在地址空间(4G)结尾处的内存. / 标准的PC地址范围不会被报告,例如在地址A0000到BFFF的被用作video memory的内存.从E0000到/ EFFFF的内存是主板指定的,将会被报告. / 所有的低位内存作为正常的内存将会被报告,处理为规范保留的标准RAM是OS的责任,例如,中断/ 向量表(0:0)以及BIOS数据区(40:0) / 调用Int15E820()函数. / 在Int15E820函数中,就象你看到的,其动作就是调用int 15 e820来获取内存的容量,也/ 许你不是太了解

4、,我在这里简单的介绍一下: / BIOS功能调用int15 功能号e820: / 传入参数: / eax: e820 / ebx: 存放“后续值”,该值是为了得到下一块物理内存段,他应该指定上一次调用此程序的返 / 回值,如果为第一次调用,则ebx必须为0。 / es:di: 缓冲区指针,指向“地址范围描述符”结构,bios会填充该结构。 / ecx: 缓冲区结构的大小,以bytes为单位。 / edx: 标志“SMAP”,BIOS会使用该标志对系统映像信息进行校验。 / 返回值: / CF:没有进位标志没有错误,sbb ecx,ecx / 其他的同传入的参数的意义一致。/ frame结构与上

5、面介绍的bios 的int 15的功能调用传入的参数是一致的 / 注意在使用bochs对这个函数进行调试的时候,你可以观察到winnt中的代/ 码和win2k ntldr中的代码没有一点区别。 / 本来打算以linux nt获取扩展内存一文中给出的内存地址样例做为实/ 际内存地址介绍的,不过在我使用bochs虚拟机调试的过程中却发 / 现,Int15E820函数只返回了两块内存,我不知道bochs是否使用了真实的/ 物理地址,然而我又不得不以我所见的事实为例来进行介绍,也许你所调/ 试的结果与我的不相同,不过原理其实是一致的,而且我使用bochs虚拟/ 机进行调试的根本目的不在这里。/ bre

6、ak ;#ifdef DEBUG1 BlPrint(E820: %lx %lx:%lx %lx:%lx %lx %lxn, Frame.Size, Frame.Descriptor.BaseAddrHigh, Frame.Descriptor.BaseAddrLow, Frame.Descriptor.SizeHigh, Frame.Descriptor.SizeLow, Frame.Descriptor.MemoryType, Frame.Key ); _asm push ax mov ax, 0 int 16h pop ax #endif / 我们以bochs调试的实际地址来计算一下,假设

7、这里是第一次调用Int15E820函数后的反回值 / 即:0000 0000 639K ARM 可以使用的基本内存 BAddr = Frame.Descriptor.BaseAddrLow; / 00000000 EAddr = Frame.Descriptor.BaseAddrLow + Frame.Descriptor.SizeLow - 1; / 00000000+639K-1 / 即:0009FBFF / 如果BaseAddrHigh超过了FFFFFFFF,则说明内存容量已经超过了32位处理器所能表示的4G内存地址/ 空间(在winnt时代还没有考虑64位处理器的情况) if (Fra

8、me.Descriptor.BaseAddrHigh = 0) if (EAddr BlockSize 0) / 检查该内存描述块是否与当前的内存描述符所描述的内存块是相临的,如果是,合并他们. (yes, / some machineswill return memory descriptors that look like this. Compaq / Prosignia machines) if (Address+Size = CurrentEntry-BlockBase) coalescing with descriptor at %lx (%lx)n CurrentEntry-Blo

9、ckBase, BlockSize);BlockBase = Address;BlockSize += Size; new descriptor at %lx (%lx)n if (Address = (CurrentEntry-BlockBase + CurrentEntry-BlockSize) CurrentEntry+;/ 第一次调用InsertDescriptor()函数插入第一个内存块到内存描述符链表时会在这里执行,创建首/ 个对内存块描述的描述符。/ 如果要插入的内存描述块与已经存在的描述符描述的内存块并不相临,那么创建新的描述符,并创建/ 结束点 if (CurrentEntr

10、y-BlockSize = 0) / If CurrentEntry-BlockSize = 0, we have reached the end of the list / So, insert the new descriptor here, and create a new end-of-list entry BlockSize = Size; +CurrentEntry; / Create a new end-of-list marker BlockBase = 0L;BlockSize = 0L; / Wait for a keypress 通过这两个函数原始的内存描述符链表就形成了

11、:(以Bochs调试出的为例) Address:00000000(000000000009FBFF)Size:639k; Type:ARM 00100000(00100000007FFFFF)Size:7M;ARR Sumain.c中包含osLoader的映射部分:/ 其实这个循环体要和下面的 if 判断语句合起来理解才算清楚,在原来的代码中我看到他们被分开,所以觉/ 得这的代码有点画蛇添足的意思,其实不然,循环找到最后一个内存描述符块,然后对他进行判断,以查看/ 你的电脑是否只有640K的内存。 while (CurrentEntry-BlockBase != 0) & (CurrentEn

12、try-BlockSize != 0) if (CurrentEntry-BlockBase = 0) &BlockSize BlockSize/1024); while (1) / 确保在内存描述符表描述的内存中确实能容纳下 osloader image / 其实这里才是我动用bochs调试器的真正原因,理由很简单,我对这里的地址感到很困惑,没有在其他/ 的代码中找到关于 edata 的什么赋值操作(除了su.asm中),所以我不能确定osloader的加载位置到/ 底是在哪里(实在是找不到一点相关的资料,因而出红疹发高烧病了,差点就 GAME OVER了)。 / 以下是bochs调试出的指

13、令代码: / mov ax,word ptr ds:0x1e00 ; ax=0x0000 ImageBase / mov dx,word ptr ds:0x1e02 ; dx=0x0030 / mov word ptr ss:bp+0xffea,ax bp+0xffec,dx / mov cx,word ptr ds:0x1e1c ; cx=0x1000 ImageSize / mov bx,word ptr ds:0x1e1e ; bx=0x0006 bp+0xffe6,cx bp+0xffe8,bx / mov word ptr ds:0x1680,ax OsLoaderBase 0x16

14、82,dx / add ax,word ptr ds:0x1e44 ; ax=0xf000 / adc dx,word ptr ds:0x1e46 ; dx=0x0032 0x1684,ax OsLoaderExports 0x1686,dx / 我不能确定OptionalHeader这条代码在反汇编出的指令中的位置,我也没有找到和这条代码相关的指 / 令,所以在这里我有一个猜测,即 ntldr 经过编译优化以后,osloader 的 Standard fields 和 NT / additional fields 被放在了固定的位置,我们可以看到 ImageBase 是 NT additio

15、nal fields 的第/ 一个字段,在bochs调试出的代码中直接访问ds:0x1e00处得来。/ 该处如果不是太明了,你可以参照一下 _IMAGE_OPTIONAL_HEADER 的结构定义(winnt.h)。 OptionalHeader = (PIMAGE_OPTIONAL_HEADER)(PUCHAR)&edata + sizeof(IMAGE_FILE_HEADER); ImageBase = OptionalHeader-ImageBase; ImageSize = OptionalHeader-SizeOfImage; OsLoaderBase = ImageBase;OsL

16、oaderExports = ImageBase + OptionalHeader-DataDirectoryIMAGE_DIRECTORY_ENTRY_EXPORT.VirtualAddress;while (ImageSize / 这个循环体看似复杂,其实他要做的事情很简单,即检验我们前面所画的内存描述符链表中是否有/ 足够的内存块能包含我们要加载的 osloader = 0) BlockEnd = CurrentEntry-BlockSize;BlockBase ImageBase) / this descriptor at least partially contains a chun

17、k / of the osloader. if (BlockEnd-ImageBase ImageSize) ImageSize = 0; / 如果有足够的内存块,那么我们将 ImageSzie 置0,以此作为验/ 证标志 else ImageSize -= (BlockEnd-ImageBase); ImageBase = BlockEnd; / look for remaining part (if any) of osloader CurrentEntry = MemoryDescriptorList; if (ImageSize 0) / 如果我们的 ImageSize 验证标志依然不为0,那么打印出错信息 / We could not relocate the osloader to high memory. Error out / and display the memory map. BlPrint(SU_NO_EXTENDED_MEMORY); %lx - %lxnRelocateLoaderSections()函数分析:之所以把这个函数单独的列出来分析,是因为他对以后的内存操作至关重要,因为在后面对内存块进行分配时,别的内存地址是被硬性的加载分配的,而只有osloader的地址是我们无法直接确定的。ULON

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1