• BIOS启动原理学习--加载第二部分代码-setup


    参考书籍 Linux内核设计的艺术

    BIOS已经把bootsect(也就是引导程序)载入内存了,它的作用就是把第二批和第三批程序陆续加载到内存中。为了把第二批和第三批程序加载到内存中的适当位置,bootsect首先做的工作就是规划内存。

    设置这些位置(内存)就是为了确保将要载入内存的代码和已经载入内存的代码及数据各在其位,互不覆盖。

    接下来,bootsect启动程序将它自身(全部的512B内容)从内存0x07C00(BOOTSEG)处复制至内存0x90000(INITSEG)处。

    执行这个操作的代码如下:
    mov ax ,#BOOTSEG
    mov ds,ax
    mov ax,#INITSEG
    mov es,ax
    mov cx ,#256
    sub si,si
    sub di,di
    rep
    movw

    sub是减法运算。
    比如
    mov ax,2
    mov bx,1
    sub ax,bx
    其中sub ax,bx就是ax中的值减bx中的值,等于1,然后把结果,也就是1,放入ax中。

    rep是字符串操作指令MOVS,CMPS等的前缀,在CX不等于0的情况下,对字符串执行重复操作

    movw解析参考点我

    bootsect复制到新位置后,bootsect会执行以下代码

    rep
    movw
    jmpi go,INITSEG
    go:mov ax,cs
    mov ds,ax

    这两行代码十分巧妙
    jmpi go,INITSEG
    go:mov ax,cs
    在内存的0x07C00和0x90000位置处有两段完全相同的代码。请大家注意,复制代码这件事本身也是要靠指令执行的,执行指令的过程就是CS和IP不断变化的过程。执行到jmpi go, INITSEG这行之前,代码的作用就是复制代码自身;执行了jmpi go, INITSEG之后,程序就转到执行0x90000这边的代码了。Linus的设计意图是跳转之后在新位置接着执行后面的mov ax, cs,而不是死循环。jmpi go, INITSEG与go: mov ax, cs配合,巧妙地实现了“到新位置后接着原来的执行序继续执行下去”的目的。厉害

  • 相关阅读:
    利用Selenium自动化web测试
    【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
    SlickGrid example 8:折线图
    SlickGrid example 7:鼠标事件
    SlickGrid example 6:Ajax加载
    SlickGrid example 5:带子项的展开收缩
    SlickGrid example 4: 过滤
    CentOS下配置iptables防火墙 linux NAT(iptables)配置
    ntp server
    parted
  • 原文地址:https://www.cnblogs.com/AmosAlbert/p/12832272.html
Copyright © 2020-2023  润新知