zoukankan      html  css  js  c++  java
  • 调试kernel时对bios加电后过程的一些心得

    http://blog.csdn.net/tianwailaibin/article/details/6975297

    前几天折腾了一下kernel 并debug了引导和初始化部分,有一些心得,更正了一直以来的很多错误认识。
    这里还是拿linux 0.00 的代码来实验,制作好引导盘后启动 bochs (已重新编译加了 –enable-debugger –enable-disasm 参数)
     
    下图是IBM PC内存的分布状况:
    (注意:0xA0000 is the pointer address to the Graphical Mode and 0xB8000 is the pointer address to the Color Text Mode and 0xB0000 is the pointer to the Monochrome text Mode. 
     
    尽管上面很多区域在bios初始化后填充了内容但其实是可以将kernel 载入除640KB – 1MB 以及4G高位内存附近的任何存储空间中。因为BIOS提供的参数数据和中断向量kernel并不使用,可以被直接覆盖。
     
    下面总结一下整个过程:
     
     1.
    加电后cpu 的 状态是:
    eax:0×00000000, ebx:0×00000000, ecx:0×00000000, edx:0×00000543
    ebp:0×00000000, esp:0×00000000, esi:0×00000000, edi:0×00000000
    eip:0x0000fff0, eflags:0×00000002, inhibit_mask:0
    cs:s=0xf000, dl=0x0000ffff, dh=0xff009bff, valid=1
    ss:s=0×0000, dl=0x0000ffff, dh=0×00009300, valid=1
    ds:s=0×0000, dl=0x0000ffff, dh=0×00009300, valid=1
    es:s=0×0000, dl=0x0000ffff, dh=0×00009300, valid=1
    fs:s=0×0000, dl=0x0000ffff, dh=0×00009300, valid=1
    gs:s=0×0000, dl=0x0000ffff, dh=0×00009300, valid=1
    ldtr:s=0×0000, dl=0×00000000, dh=0×00000000, valid=0
    tr:s=0×0000, dl=0×00000000, dh=0×00000000, valid=0
    gdtr:base=0×00000000, limit=0xffff
    idtr:base=0×00000000, limit=0xffff
    dr0:0×00000000, dr1:0×00000000, dr2:0×00000000
    dr3:0×00000000, dr6:0xffff0ff0, dr7:0×00000400
    cr0:0×00000010, cr1:0×00000000, cr2:0×00000000
    cr3:0×00000000, cr4:0×00000000

    通过cs:ip可以发现第一条指令是在0xf000:0xfff0 执行的. 如果只读过大学那些涉及皮毛的书你肯定会认为其物理地址就是0xffff0 (0xf000<<1+0xfff0)。但这样的认识仅仅是针对i8086 ,真正的x86 架构即i80386 之后是这样的:cpu刚刚设置cs:0xf000的时候其实并不是像课本上说的那样在实模式下。此时的物理地址需要根据cs中的隐藏寄存器dl=0x0000ffff, dh=0xff009bff中去查。这个其实就是段描述符(至少在保护模式下是,这里也暂时这样称呼吧) dh的最高8位和最低8位以及dl的高16位组成了32位段基址:0xffff0000 再加上ip:0xfff0 那么物理地址就是0xfffffff0 正好是4GB空间的最后16Byte。
    即执行的第一条指令也在这里:
    (0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b         ; ea5be000f0
    跳转到真正BIOS程序的入口地址

    这里做很精妙,因为intel考虑到兼容性问题设置了cpu加电后cs:ip=0xf000:0xfff0: 如果是i8086那么该跳转指令将在16位cpu可寻址最大空间1MB(基本内存)的最后16Byte,如果是i80386则将在32位cpu可寻址最大 空间4GB的最后16Byte。

    再反汇编看一下:



                      
                      
            


                               
                        
                                             
                       
                                  
                                      
                       
                       
                       
                       

    <

                   


                  


                 



            

                   



















                           
                                                                           
                                                                    
                               
                                                                           
                                                                    
            


    <>""""""""""""""""""""""""""""''''''<>

  • 相关阅读:
    FlashDevelop视频教程三:多工程的使用及编译SWC
    FlashDevelop插件ASCompletion
    c#实现MD5加密
    FlashDevelop视频教程一:简介及安装
    FlashDevelop4 快捷键
    FlashDevelop视频教程四:FLA工程调试和一些技巧
    一个简单的c#操作XML文件的类,只能操作一层的节点
    验证用户的存储过程
    MOSS模态窗口应用
    二进制图片格式转换
  • 原文地址:https://www.cnblogs.com/ztguang/p/12648221.html
Copyright © 2011-2022 走看看