美文网首页
引导启动程序之bootsect.s

引导启动程序之bootsect.s

作者: 1f706595a1cd | 来源:发表于2018-12-01 20:36 被阅读0次

1. P52,47~56

start :
    mov ax, #BOOTSEG             
    mov ds, ax
    mov ax, #INITSEG
    mov es, ax
    mov cx, #256
    sub si, si
    sub di, di
    rep               !  重复执行它的下一条语句movw,直到cx中的数值为0。这里是循环执行256次
    movw              !  以字节为单位,从源地址往目的地址搬移数据,si、di自增
    jmpi go,INITSEG   !  jmpi--段间跳转指令,CS = INITSEG,IP = go,即跳转到INITSEG:go处执行

标志寄存器EFlags

方向标志DF(Direction Flag),用于决定执行完一次串操作之后,变址寄存器ESI/EDI是加还是减

  • DF=0,自加
  • DF=1,自减

串操作

  • 取串(LODS),存串(STOS)、移串(MOVS)
  • 可以按照字节(B)、字(W)、双字(D)进行数据处理,

2. P53,62

扇区

一个扇区是512byte,setup 程序大约为 4 个扇区

段地址+偏移地址

  • x86处理器地址总线是20位,而内部数据总线、寄存器都是16位的。
  • 如何用16位寄存器表示20位?物理地址=段地址 << 4 + 偏移地址
  • eg
    ss = 0x9000,sp=0xff00,那么sp指向的地址是0x90000 + 0xff00 = 0x9ff00

3. P53,67

INT 0x13 磁盘服务程序
  • 功能号0x00, 复位驱动器

    AH = 0X00,DL = 需要复位的驱动器号。

  • 功能号0x02, 读磁盘扇区到内存

    AH = 0x02,AL = 需要读出的扇区数量;
    CH = 磁道(柱面)号的低 8 位; CL = 开始扇区(0-5 位),磁道号高 2 位(6-7);
    DH = 磁头号; DL = 驱动器号(如果是硬盘则位 7 要置位);
    es:bx 指向数据缓冲区; 如果读取失败则 CF 标志置位

    返回信息

    传输成功:CF=0,AH=00H,AL=传输的扇区数
    传输失败:CF=1,AH=状态代码(见下表)

01H — 非法命令 02H — 地址目标未发现 03H — 磁盘写保护(软盘) 05H — 复位失败(硬盘)
06H — 软盘取出(软盘) 07H — 错误的参数表(硬盘) 08H — DMA越界(软盘) 09H — DMA超过64K界限
0AH — 错误的扇区标志(硬盘) 0BH — 错误的磁道标志(硬盘) 0CH — 介质类型未发现(软盘) 0DH — 格式化时非法扇区号(硬盘)
0EH — 控制数据地址目标被发现(硬盘) 0FH — DMA仲裁越界(硬盘) 10H — 不正确的CRC或ECC编码 11H — ECC校正数据错(硬盘)
20H — 控制器失败 40H — 查找失败 80H — 磁盘超时(未响应) AAH — 驱动器未准备好(硬盘)
BBH — 未定义的错误(硬盘) CCH — 写错误(硬盘) E0H — 状态寄存器错(硬盘) FFH — 检测操作失败(硬盘)
  • 功能号0x08,读取磁盘驱动器参数
    AH = 0x08,DL = 驱动器号(如果是硬盘则要置位 7 为 1)
    返回信息

    如果出错则 CF 置位,并且 AH = 状态码。
    AH = 0, AL = 0
    BL = 驱动器类型(AT/PS2)
    CH = 最大磁道号的低 8 位,CL = 每磁道最大扇区数(位 0-5),最大磁道号高 2 位(位 6-7)
    DH = 最大磁头数,DL = 驱动器数量
    es:di 软驱磁盘参数表

4. P54,92~102

INT 0x10

CSDN

由 BIOS 对屏幕及显示器所提供的服务程序

    ! Print some inane message
    mov ah, #0x03       ! read cursor pos,AH=0x03,读取光标,为了获取光标当前的行列
    xor bh, bh           !bh = 页号
    int 0x10               
    
    mov cx, #24
    mov bx, #0x0007     ! page 0, attribute 7 (normal)
    mov bp, #msg1
    mov ax, #0x1301     ! write string, move cursor
    int 0x10

读取光标是必要的,为了获取光标位置(DH、DL)

  • AH=3,读光标位置

    BH = 页号
    CH = 光标开始行
    CL = 光标结束行
    DH = 行
    DL = 列

  • AH=13,表示显示字符串

    ES:BP = 串地址
    CX = 串长度
    DH, DL = 起始行列
    BH = 页号
    BL = 07H,正常的黑底白字

P55,151~155

read_it:
    mov ax, es
    test ax, #0x0fff
die:    jne die         ! es must be at 64kB boundary
    xor bx, bx         ! bx is starting address within segment

test指令

  • test的解释( Intel技术手册)

TEMP ← SRC1 AND SRC2 ;
  SF ← MSB(TEMP) ;
IF TEMP = 0
  THEN ZF ← 1 ;
  ELSE ZF ← 0 ;
  FI:
  PF ← BitwiseXNOR(TEMP[0:7]);
  CF ← 0 ;
  OF ← 0 ;

  • 对代码的解释
    • test是进行位与操作,相与等于0,说明ax=es=0x1000,ZF=1
    • JNE/JNZ都是ZF标志位为0时跳转,如果es在64kb处,则顺序执行;否则,死锁

子程序151~218

实现功能

该子程序将系统模块加载到内存地址 0x10000 处,并确定没有跨越 64KB 的内存边界。我们试图尽快 地进行加载,只要可能,就每次加载整条磁道的数据

执行流程

  • read_it

    • 检测读入的数据是否在内存地址64kB处
    • 是,则执行rp_read;否,则死锁
  • rp_read

    • 首先判断是否已经读完
    • 是,返回调用处;否,执行ok1_read
  • ok1_read

    • 取当前磁道的扇区数,计算是否超过64kB
    • 是,计算能读取的最大值;否,执行ok2_read
  • ok2_read

    • 执行读取操作(跳转到了read_track)
    • 传输的扇区数存储在AL中,判断是否已经读完当前磁道的所有扇区
    • 是,顺序执行,如果当前磁道是0,则磁道号+1,执行ok4_read;如果磁道号是1,则直接跳转到ok4_read;否,执行ok3_read
  • ok3_read

    • 计算当前已读扇区数量,将读取位置存储在bx中
    • 跳转到rp_read,继续读取
  • ok4_read

    • 保存磁道号,清空ax
    • 如果未读完,进入ok3_read;否则,调整基址跳转到rp_read
  • read_track

    • 对通用 寄存器压栈保护
    • 设置要读取的驱动器号、磁道号、扇区,然后调用INT 0x13软件中断
    • 调用正确,返回调用处;否则,执行bad_rt,驱动器复位,然后重新跳转执行read_track
  • kill_motor

    关闭软驱的马达,这样我们进入内核后它处于已知状态,以后也就无须担心它了

子程序执行流图

8086寄存器

数据寄存器

  • AX (Accumulator):累加寄存器,也称之为累加器;
  • BX (Base):基地址寄存器;
  • CX (Count):计数器寄存器;
  • DX (Data):数据寄存器;

指针寄存器

  • SP (Stack Pointer):堆栈指针寄存器;
  • BP (Base Pointer):基指针寄存器;

变址寄存器

  • SI (Source Index):源变址寄存器
  • DI (Destination Index):目的变址寄存器;

控制寄存器

  • IP (Instruction Pointer):指令指针寄存器;
  • FLAG:标志寄存器;

段寄存器:

  • CS (Code Segment):代码段寄存器;
  • DS (Data Segment):数据段寄存器;
  • SS (Stack Segment):堆栈段寄存器;
  • ES (Extra Segment):附加段寄存器

相关文章

  • 引导启动程序之bootsect.s

    1. P52,47~56 标志寄存器EFlags 方向标志DF(Direction Flag),用于决定执行完一次...

  • 【笔记】Linux引导启动程序1806

    *内核版本0.11,《Linux内核完全注释》引导启动程序(boot)(bootsect.s;head.s;set...

  • 【文魁大脑读书会】52/60马帅《linux内核》

    阅读时间:2015年12月2日 阅读笔记:关于boot中bootsect.s的加载 在引导加载程序 bootsec...

  • Android系统启动

    init进程 启动电源,加载引导程序,引导程序启动Linux内核,Linux内核加载完成后,首先启动 init 进...

  • 越狱简介

    引导程序 启动设备时,所有的设备都会有引导程序,引导 ROM 只读内存,系统相关,验证,在启动系统之前验证,如果通...

  • 源码分析Android启动流程

    Android系统启动流程. 当系统引导程序启动Linux内核时, 内核会加载各种数据结构和驱动程序. 有了驱动之...

  • Android应用程序启动简述

    1.启动电源以及系统启动 按下电源,加载引导程序BootLoader到RAM 2.引导程序BootLoader B...

  • Linux 启动过程

    1,内核引导 bios开机自检,按照其上设置的启动设备来启动,启动设备上的grub程序开始引导linux.linu...

  • APP启动优化

    APP启动流程 1,系统的启动 1.打开电源 引导芯片代码加载引导程序Boot Loader到RAM中去执行 ...

  • 操作系统(linux0.11)的启动

    概述 linux系统启动涉及三个汇编文件,bootsect.s,setup.s,head.s,下图为启动盘的代码模...

网友评论

      本文标题:引导启动程序之bootsect.s

      本文链接:https://www.haomeiwen.com/subject/oiwrcqtx.html