操作系统学习setup_硬盘加载

一、可以通过int 0x13例程或者通过0x1F0~0x1F7这8个端口操作硬盘

        1、0x13例程主要就是设置对参数,其他跟操作软盘一样,dl=0x80即可。

        2、通过0x1F0~0x1F7这8个端口操作硬盘稍微复杂一点。

二、bochs配置文件需要稍加修改,其实也不用手工来做。如下:

        1、运行bochs,选3.Edito ptions -->12.Disk &Boot options-->3.ATA channel 0(出现选项,直接回车确认即可,选完最后一项会自动退到上级菜单)-->7.First HD/CD on channel 1(输入disk,输入文件名,我不想麻烦,直接选软盘的映像a.img,选flat模式。cylinders输入80,heads输入2,sectors per track输入18,sector size输入512,可以看出以上参数都是按照a.img的参数设置的。其他参数都选默认值就行)-->返回到主菜单选4.保存。文件名用diskboot了,这个随心意。

        2、打开diskboot文件看一下参数是否正确,把boot:后面改为disk。

        3、修改magic_break,display_library后面的选项。其他不用动,如下:

display_library: x, options="gui_debug"

boot: disk

ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="a.img", mode=flat, cylinders=80, heads=2, spt=18, sect_size=512, model="Generic 1234", biosdetect=auto, translation=auto

magic_break: enabled=1

三、Makefile 增加一行

bootFromDisk:
    bochs -q -f diskboot

四、修改boot.asm把读软盘改为读硬盘。

        1、用int 0x13方式

read_setup:
    mov dh, 0 ; driver head
    mov dl, 0x80 ; driver number
    mov ch, 0 ; cycle number
    mov cl, 2 ; start sector
    mov bx, SETUP_LOAD_ADDR ; store to memory address
    mov ah, 2 ; function number for read disk
    mov al, 1 ; read 1 sector
    int 0x13  ; handle disk driver bios routine
    pushf     ; flags register push stack
    pop si
    and si, 0x0001 ; CF set to 1 when operate disk error
    cmp si ,0
    jz .done
    jmp read_setup
.done:
    ret

        同操作软盘这里就只是把dl的值改为了0x80。

        运行了一下,成功。在没有改dl的值之前也运行了一次,也成功了。感觉int 0x13不挑食。也不知道是不是因为模拟环境的原因。

        2、用操作硬盘控制器端口方式读硬盘:

        有8个端口需要操作:

        0x1F0--读写的数据都放这里面,共16bit。

        0x1F1--读出错时放错误码,写数据的时候放功能码,8bit。

        0x1F2--读写多少个扇区,8bit。

        0x1F3--LBA地址的0~7位

        0x1F4--LBA地址的8~15位

        0x1F5--LBA地址的16~23位                                           

        0x1F6:每一位取值的意义
            ________________________________
            |  7  |    6    |  5  |    4    |  3  |  2  |  1  |  0  |
            -----------------------------------------------------
            |  1  | LBA  |  1  | DRV  |    Head number | 
            -----------------------------------------------------
        LBA位:1-LBA地址模式;0-CSH地址模式
        DRV位:1-从盘模式;0-主盘模式
        Head number:CHS模式下传递磁头号(0~15);LBA模式下传递lba地址24~28位。

     

         0x1F7:status register (read only)

        用作状态寄存器时是一个只读寄存器。IDE控制器使用它来返回一些信息,这些信息取决于正在执行的命令。每一位意义如下:


        _________________________________________
        |    7   |    6    |    5    |    4   |    3    |    2    |   1   |    0   |
        ---------------------------------------------------------------------
        | BSY | RDY | WFT | SKC | DRQ | COR | IDX | ERR | 
        ---------------------------------------------------------------------
BSY: 值为1时,表示硬盘控制器正在执行一个命令。除了digital output寄存器外的寄存器都不能被访问。
RDY:值为1时,表示硬盘控制器已经准备好执行命令,并且驱动器正在以正确的速度旋转。
WFT: 值为1时,表示硬盘控制器检测到一个写入故障。
SKC: 值为1时,表示读写头已经就位(寻道结束)。
DRQ: 值为1时,表示可以访问数据寄存器。写数据时,表示硬盘控制器等待数据;读数据时,表示硬盘控制器正发送数据。
COR: 值为1时,表示控制器必须通过使用ECC字节来纠正数据(Error Correction Code,纠错码:系数末尾的额外字节,用于验证其完整性,有时还用于纠正错误)。
IDX: 值为1时,表示控制器重新标记了索引标记(不是硬盘上的孔)。
ERR: 值为1时,表示发生了错误。错误代码已放入0x1F1中
   

0x1F7:command register (write only)

     用作命令寄存器时,是一个只写寄存器。它接受对IDE控制器的命令。请注意,大多数命令都意味着一些值已放置在sector、cylinder等寄存器中。总是最后发送命令(将命令传送到0x1F7)。相关命令:

      1X:重新校准磁盘。所有(10~1F)的命令都将导致重新校准磁盘。此命令没有参数,只需将命令代码写入命令寄存器,然后等待就绪状态再次变为活动状态。
      20:读扇区,失败将重试。21:读扇区,失败不重试。22:需通过ECC校验。23:失败重试并且要通过ECC校验。这个命令在LBA模式下有效。当命令完成(DRQ激活)时,您可以从数据寄存器中读取256个字(16位)。
      30:写扇区,失败将重试。31:写扇区,失败不重试。22:需通过ECC校验。23:失败重试并且要通过ECC校验。

        其他命令不再列出,可参考:https://www.unige.ch/medecine/nouspikel/ti99/ide.htm,register那一部分。

由上面的资料可以写程序了:

readHD:
;---- prepart register ----
    mov al, 1       ; -- sector count for read
    mov dx, 0x1f2
    out dx, al

    inc dx          ; 0x1f3  -- start address for read
    mov al, 2
    out dx, al
    inc dx          ; 0x1f4
    mov al, 0
    out dx, al
    inc dx          ; 0x1f5
    out dx, al

    inc dx          ; 0x1f6
    mov al, 0xe0    ; | 1 | lba | 1 | drv | lba highest four bit address |
                    ; | 1    1    1    0    0000  -- set lba mode(0xE0)  |
;---- wait RDY signal ----
    inc dx          ; 0x1f7
.waitRDY:
    nop
    in al, dx
    test al, 0x40   ; | BSY | RDY | WFT | SKC | DRQ | COR | IDX | ERR |
                    ; |  -    1      -     -     -     -     -     -  |0x40
    jz .waitRDY
;---- load read HD command ----
    mov al, 0x20
    out dx, al
;---- wait DRQ signal ----
.waitDRQ:
    nop
    mov dx, 0x1f7
    in al, dx
    test al, 0x08   ; | BSY | RDY | WFT | SKC | DRQ | COR | IDX | ERR |
                    ; |  -    -      -     -     1     -     -     -  |0x08
    jz .waitDRQ
;---- read data and write to memory ----
    mov cx, 256
    mov di, SETUP_LOAD_ADDR
    mov dx, 0x1f0
.readDT:
    in ax, dx
    mov word[di], ax
    inc di
    inc di
    loop .readDT

    ret

  参考文章:CHS和LBA逻辑块地址_lba chs-CSDN博客文章浏览阅读9.2k次,点赞7次,收藏36次。LBA简介磁盘读取发展IO操作读取硬盘的三种方式:chs方式 :小于8G (8064MB)LBA28方式:小于137GBLBA48方式:小于144,000,000 GBLBA方式访问使用了data寄存器,LBA寄存器(总共3个),device寄存器,command寄存器来完成的。LBA28和LBA48方式:LBA28方式使用28位来描述一个扇区地..._lba chshttps://blog.csdn.net/jadeshu/article/details/89072512

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值