• 调试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。

    再反汇编看一下:



                      
                      
            


                               
                        
                                             
                       
                                  
                                      
                       
                       
                       
                       

    <

                   


                  


                 



            

                   



















                           
                                                                           
                                                                    
                               
                                                                           
                                                                    
            


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

  • 相关阅读:
    阿里妈妈MaxCompute架构演进_-_AON(MPI)集群
    阿里云ECS部署Grafana接入zabbix
    ECS实例RAM角色实践
    上海云栖—人工智能-视觉计算专场预热
    阿里云论坛版主制作最新教程汇总贴
    移动相关的css
    GULP入门(一)
    mongodb+nodejs 增删查的demo
    nodejs+express 初学(三)
    nodejs+express 初学(二)
  • 原文地址:https://www.cnblogs.com/ztguang/p/12648221.html
Copyright © 2020-2023  润新知