硬盘介绍 +让MBR使用硬盘

硬盘介绍

硬盘发展简史
  • 此设备用磁头来读写数据,用盘片来存储数据,以后的硬盘都是以这样的模式发展。这个磁头可以直接移动到盘片上的任何 块存储单元,从而实现了随机存储
  • 温彻斯特技术:镀磁盘片在密封空间中高速自转,磁头悬浮在盘片上方,固定在磁头臂上沿盘片径向移动
  • 盘片自转速度是存取数据速度的关键,如果磁头与盘片接触,受摩擦力的影响,想快也快不了
  • 由于磁头和盘片各自的运动,再加上如此近的距离,所以哪怕一点灰尘都会造成磁盘的损伤。于是,磁头、盘片被密封在了一个盒子里
  • 寻道时间:磁头臂移动到目标位置的时间称为寻道时间
硬盘工作原理
  • 盘片固定在主轴上随主轴高速转动
  • 故一个盘片上对应2个磁头
  • 磁头不会自己在盘片上移动,它需要被固定在右边的磁头臂上。磁头位于磁头臂的另 端,所以也跟着呈钟摆运动,运动轨迹是个 弧线,并不是直线。能否找到数据,只跟它最终落点有关,和中间路径形状是没关系的
  • 同心环是磁道,同心环上的每一小块称为扇区,大小是512字节。磁道的编号和磁头一样也是从0开始的,相同编号的磁道组成的管状区域就称为柱面。各磁道内的扇区是以1开始编号的,一个磁道有63个扇区
  • 如果待写入的数据要占用多个磁道时,除了写的时候要变换磁头到新磁道,将来读出来的时候也需要变换磁道,也就是需要多次寻道才能完成数据的完整读写。所以使用多个磁头,按柱面存取就可以减少寻道时间。
  • 可以使用磁头号、磁道号、扇区号唯一定位一个硬盘
    在这里插入图片描述
主机支持硬盘的个数
  • 针对硬盘的IO接口是硬盘控制器

在这里插入图片描述

操作硬盘的步骤

  • 先选择通道,往该通道的 sector count 寄存器中写入待操作的扇区数。
  • 往该通道上的三个 LBA 寄存器写入扇区起始地址的低 24 位。
  • 往 device 寄存器中写入 LBA 地址的 24~27 位,并置第6位为 ,使其为 LBA 模式,设置第4位,选择操作的硬盘( master 硬盘或 slave 硬盘)。
  • 往该通道上的 command 寄存器写入操作命令。
  • 读取该通道上的 status 寄存器,判断硬盘工作是否完成。
  • 如果以上步骤是读硬盘,进入下一个步骤。否则,完工。
  • 将硬盘数据读出。

让MBR使用硬盘

  • MBR的任务:
    负责从硬盘上把 loader 加载到内存,并将接力棒交给它。
  • loader 的加载地址选为 0x900,把 loader 放到了2扇区
    boot.inc
    ;-------------	 loader和kernel   ----------
    LOADER_BASE_ADDR equ 0x900 
    LOADER_START_SECTOR equ 0x2
    
  • 修改mbr.S,可以让 MBR 使用硬盘
    ;主引导程序 
    ;------------------------------------------------------------
    %include "boot.inc"
    SECTION MBR vstart=0x7c00         
       mov ax,cs      
       mov ds,ax
       mov es,ax
       mov ss,ax
       mov fs,ax
       mov sp,0x7c00
       mov ax,0xb800
       mov gs,ax
    
    ; 清屏
    ;利用0x06号功能,上卷全部行,则可清屏。
    ; -----------------------------------------------------------
    ;INT 0x10   功能号:0x06	   功能描述:上卷窗口
    ;------------------------------------------------------
    ;输入:
    ;AH 功能号= 0x06
    ;AL = 上卷的行数(如果为0,表示全部)
    ;BH = 上卷行属性
    ;(CL,CH) = 窗口左上角的(X,Y)位置
    ;(DL,DH) = 窗口右下角的(X,Y)位置
    ;无返回值:
       mov     ax, 0600h
       mov     bx, 0700h
       mov     cx, 0                   ; 左上角: (0, 0)
       mov     dx, 184fh		   ; 右下角: (80,25),
    				   ; 因为VGA文本模式中,一行只能容纳80个字符,共25行。
    				   ; 下标从0开始,所以0x18=24,0x4f=79
       int     10h                     ; int 10h
    
       ; 输出字符串:MBR
       mov byte [gs:0x00],'1'
       mov byte [gs:0x01],0xA4
    
       mov byte [gs:0x02],' '
       mov byte [gs:0x03],0xA4
    
       mov byte [gs:0x04],'M'
       mov byte [gs:0x05],0xA4	   ;A表示绿色背景闪烁,4表示前景色为红色
    
       mov byte [gs:0x06],'B'
       mov byte [gs:0x07],0xA4
    
       mov byte [gs:0x08],'R'
       mov byte [gs:0x09],0xA4
    	 
       mov eax,LOADER_START_SECTOR	 ; 起始扇区lba地址
       mov bx,LOADER_BASE_ADDR       ; 写入的地址
       mov cx,1			 ; 待读入的扇区数
       call rd_disk_m_16		 ; 以下读取程序的起始部分(一个扇区)
      
       jmp LOADER_BASE_ADDR
           
    ;-------------------------------------------------------------------------------
    ;功能:读取硬盘n个扇区
    rd_disk_m_16:	   
    ;-------------------------------------------------------------------------------
    				       ; eax=LBA扇区号
    				       ; ebx=将数据写入的内存地址
    				       ; ecx=读入的扇区数
          mov esi,eax	  ;备份eax
          mov di,cx		  ;备份cx
    ;读写硬盘:
    ;第1步:设置要读取的扇区数
          mov dx,0x1f2
          mov al,cl
          out dx,al            ;读取的扇区数
    
          mov eax,esi	   ;恢复ax
    
    ;第2步:将LBA地址存入0x1f3 ~ 0x1f6
    
          ;LBA地址7~0位写入端口0x1f3
          mov dx,0x1f3                       
          out dx,al                          
    
          ;LBA地址15~8位写入端口0x1f4
          mov cl,8
          shr eax,cl
          mov dx,0x1f4
          out dx,al
    
          ;LBA地址23~16位写入端口0x1f5
          shr eax,cl
          mov dx,0x1f5
          out dx,al
    
          shr eax,cl
          and al,0x0f	   ;lba第24~27位
          or al,0xe0	   ; 设置7~4位为1110,表示lba模式
          mov dx,0x1f6
          out dx,al
    
    ;第3步:向0x1f7端口写入读命令,0x20 
          mov dx,0x1f7
          mov al,0x20                        
          out dx,al
    
    ;第4步:检测硬盘状态
      .not_ready:
          ;同一端口,写时表示写入命令字,读时表示读入硬盘状态
          nop
          in al,dx
          and al,0x88	   ;第4位为1表示硬盘控制器已准备好数据传输,第7位为1表示硬盘忙
          cmp al,0x08
          jnz .not_ready	   ;若未准备好,继续等。
    
    ;第5步:从0x1f0端口读数据
          mov ax, di
          mov dx, 256
          mul dx
          mov cx, ax	   ; di为要读取的扇区数,一个扇区有512字节,每次读入一个字,
    			   ; 共需di*512/2次,所以di*256
          mov dx, 0x1f0
      .go_on_read:
          in ax,dx
          mov [bx],ax
          add bx,2		  
          loop .go_on_read
          ret
    
       times 510-($-$$) db 0
       db 0x55,0xaa
    
  • loader.S
    %include "boot.inc"
    section loader vstart=LOADER_BASE_ADDR
    
    ; 输出背景色绿色,前景色红色,并且跳动的字符串"1 MBR"
    mov byte [gs:0x00],'2'
    mov byte [gs:0x01],0xA4     ; A表示绿色背景闪烁,4表示前景色为红色
    
    mov byte [gs:0x02],' '
    mov byte [gs:0x03],0xA4
    
    mov byte [gs:0x04],'L'
    mov byte [gs:0x05],0xA4   
    
    mov byte [gs:0x06],'O'
    mov byte [gs:0x07],0xA4
    
    mov byte [gs:0x08],'A'
    mov byte [gs:0x09],0xA4
    
    mov byte [gs:0x0a],'D'
    mov byte [gs:0x0b],0xA4
    
    mov byte [gs:0x0c],'E'
    mov byte [gs:0x0d],0xA4
    
    mov byte [gs:0x0e],'R'
    mov byte [gs:0x0f],0xA4
    
    jmp $		       ; 通过死循环使程序悬停在此
    
  • 编译:
    nasm 使用 -I 来指定库目录,咱们在 inlcude 中放了 boot.inc
    $ nasm -I include/ -o bmr.bin mbr.S
    $ nasm -I include/ -o loader.bin loader.S
    
  • 写入磁盘
    dd if=./test/mbr.bin of=hd60M.img bs=512 count=1 conv=notrunc
    dd if=./test/loader.bin of=hd60M.img bs=512 count=1 seek=2 conv=notrunc
    
  • 结果:
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值