[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: how could i get the hexadecimal content in memory at address FFFF0000-FFFFFFF0?



2008/7/16 Taishan <taishan1982@gmail.com>:
>    首先说声抱歉,研究了一下Intel的手册,发现之前的我理解有错误,在此更
> 正一下。
>
>    我之前说的对于8086、8088没有错误,但根据Intel的手册,80386以后的CPU
> 情况有了改变。 首先还是要详细说明一下"段:偏移"地址到"线性"地址的转换过
> 程。这个过程可以分为两步:
>    第一步是根据一定规则将"段"映射为一个"基址",即段的起始点。
>    第二步是将"基址"加上"偏移"得到线性地址。
>
>    在实模式与保护模式下,第一步的操作是不同的。
>    实模式下16位的"段"到"基址"的映射规则就是乘以16,即左移4位,形成20位
> 的基址,然后再加上16位或8位的偏移(指令的不同,偏移的长度有所不同)得到
> 线性地址,而在实模式下线性地址与物理地址相同,可以直接用来访问内存。
>    而在保护模式下,"段"到"基址"的映射是通过CPU中叫做描述符表的数据结构
> 来进行的。描述符表中的每一条记录包含了一个段的基址,长度,类型,特权等级
> 等信息,在描述符表中查找"段"所对应的记录,得到这个段的基址(32位),然后
> 将基址加上偏移(32位,16位或8位),得到线性地址。如果没有开启页交换机
> 制,那么线性地址就是物理地址;如果开启了页交换机制,那么还要通过页表将线
> 性地址转换成物理地址才能使用。关于描述符表和分页交换机制这里就不详细说明
> 了。
>    因为要通过查表才能确定"基址",会对性能产生影响,因此每个段寄存器除了
> 可见的16位之外,还有一个不可见的32位"基址"部分,每次段寄存器的可见部分改
> 变时,通过查表或计算产生的"基址"会记录在段寄存器的"基址"部分。如果下次使
> 用时可见部分没有改变,则不用去再次查表或计算基址,直接从寄存器的"基址"部
> 分直接拿来用就可以了。
>    说了这么多就是为了说明段寄存器的不可见基址部分和线性地址的产生方式,
> 理解了这些那么CPU的初始情况就好说了。系统复位时,CPU运行在实模式下,CS寄
> 存器可见部分被初始化为F000H,EIP寄存器(IP寄存器的32位扩展,IP是EIP的低十
> 六位)被初始化为0000FFF0H,注意,与一般实模式时不同的是,CS的不可见基址
> 部分不是被初始化为F000H * 10H = F0000H,而是被初始化为 FFFF0000H,所以取指
> 令时是用CS的"基址"部分加上EIP产生的第一条指令的地址是:
>        FFFF0000H + 0000FFF0H = FFFFFFF0H
> 这种情况一直持续到CS的可见部分第一次被改变(长跳转或远调用等)时结束,
> 当CS被改变时,其基址部分就会按照正常的规则产生。因为CS的可见部分被初始化
> 为F000H,因此像
>        jmp F000:aa00
> 这样的指令并没有改变CS的可见部分,因此不会改写其"基址"部分,只有在CS可见
> 部分装入与F000H不同的值,才会对"基址"部分进行重新计算。
>    综上所述,80386及其以后的CPU的PC机是将BIOS映射到32位地址空间的最后一
> 部分,而不是像8086那样映射到20位地址空间的最后,这就解释了用flashrom读出
> 的BIOS是512K了,如果是映射到20为的地址空间,岂不是要占用一半的地方,而映
> 射到32位的地址空间就合理多了,即FFF80000H 至 FFFFFFFFH。
>    哎,犯了经验主义错误,以后一定要认真啊,
>
> 在008-07-15二的 21:04 +0800,Star Liu写道:
>> 非常感谢,我估计你比大学里的老师讲得更详细:)
>> 我按照你的方法已经找到我的BIOS的入口了,(7FFF0 d到 7FFFF)的前五个字节是 ea aa ff 00 f0,接下来我就可以开始跟踪机器码了:)
>> 这么看来intel cpu manul的确有问题,它说的第一条指令应该是near jmp,看来是不对的,因为ea是far jmp.
>> 那么bios也的确应该在1M内存以内,而不是FFFF0000-FFFFFFF0,我实在不明白怎么会有这么严重的bug....
>>

明白了,我犯了细节错误,以为far jump就一定会reload base register,原来必须要和以前的值不同才会reload, CPU手册还是对的:)

-- 
Regards!
Star
Shanghai, China

Reply to: