Chinaunix首页 | 论坛 | 博客
  • 博客访问: 267213
  • 博文数量: 107
  • 博客积分: 305
  • 博客等级: 二等列兵
  • 技术积分: 417
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 09:42
文章分类

全部博文(107)

文章存档

2014年(3)

2013年(41)

2012年(34)

2011年(28)

2008年(1)

分类:

2011-06-13 00:31:52

原文地址:我的OS(4)---- 软盘操作 作者:fireaxe

本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net 

Cpu启动时,如果在bios中设置了从软盘启动,则bios会自动把软盘的第一个扇区(512字节)搬移到0x7c00,然后会从0x7c00开始运行,我们需要在这512字节的程序中实现把boot从软盘中搬移到内存中的功能。

此时x86系列的cpu还处在实模式中,可以利用bios提供的中断完成软盘读写,也就是著名的int 13

  软盘操作 1.1      软盘结构

1.44M软盘为例,软盘有上、下两个盘面,每个盘面被划分为80track,每个track被划分为18Sector,每个Sector大小为512 BYTES

2×80×18×5121440×10241.44MB

如果是单纯的进行软盘读写操作,知道软盘的这些知识就够了。

1.2      软盘读写

中断号

寄存器

作用

13h

ah=00h      al=驱动器号(0表示A盘)

复位软驱

ah=02h      al=要读扇区数

ch=磁道号   cl=起始扇区号

dh=磁头号   dl=驱动器号

es:bx=数据缓冲区

cl/ch/dh/dl指向的扇区开始读取al个扇区的数据到es:bx指向的缓冲区

ah=03h      al=要写扇区数

ch=磁道号   cl=起始扇区号

dh=磁头号   dl=驱动器号

es:bx=数据缓冲区

es:bx指向的缓冲区读取al个扇区的数据写入cl/ch/dh/dl指向的al个扇区

对于软盘来说, DL=00表示A盘)

CL的取值范围是:1—18

CH的取值范围是:0—79

DH 的取值范围是:0—1

如果软盘的CLCHDH取值超过了范围,中断调用出错。

使用int13时对应扇区数的计算方法如下:

 

1.3      软盘编程

用软盘存放操作系统时,bios只会把前512个字节(即第一个扇区,引导区)读入内存的0x7c00处执行。程序的长度也被限制在了512字节大小,一个出入保护模式的程序就会超出。

为了突破512字节的限制,需要在这个扇区内放置一段引导程序,用于把后面的程序加载到内存中。这也是第一个扇区被称为引导区的原因。

下面的就是一段简单的加载程序,reset软驱后从LABEL_SECTOR2开始读入17个扇区。加上0号扇区(引导区),一共是18个扇区,也就是第一个磁道。这是因为13号中断不能跨磁道读取,所以这里只读入第一个磁道剩下的17个扇区。

    ; reset floppy

    xor ah, ah

    xor dl,  dl

    int 13h

   

    ; read sector 2 to memory

    mov ah, 03h

    mov al, 11h

    mov ch, 00h

    mov cl, 03h

    mov dh, 00h

    mov dl, 00h

    mov bx, 0100h

    int 13h

下面的程序用于保证除引导程序外的所有程序都在引导区之外,完成把磁盘内容拷贝入memory的操作后,就会跳入LABEL_SECTOR2

       jmp LABEL_SECTOR2

 

; fill boot sector

    times 510 - ($ - $$) db 1

    dw 0xaa55

 

; Sector 2

LABEL_SECTOR2:

下面是完整的程序代码

       org 07c00h

    jmp LABEL_BEGIN

 

LABEL_BEGIN:

    mov ax, cs

    mov ds, ax

    mov ss, ax

    mov es, ax

   

    ; reset floppy

    xor ah, ah

    xor dl,  dl

    int 13h

   

    ; read sector 2

    mov ah, 02h

    mov al, 01h

    mov ch, 00h

    mov cl, 02h

    mov dh, 00h

    mov dl, 00h

    mov bx, LABEL_SECTOR2

    int 13h

 

       jmp LABEL_SECTOR2

 

; fill boot sector

    uutimes 510 - ($ - $$) db 0

    dw 0xaa55

 

; Sector 2 jmp into loader

;      org 0100h

LABEL_SECTOR2:

       mov ax, cs

       mov ds, ax

       mov es, ax

       call  DispStr                 ; 调用显示字符串例程

       jmp  $                   ; 无限循环

DispStr:

       mov ax, BootMessage

       mov bp, ax                   ; ES:BP = 串地址

       mov cx, 16                   ; CX = 串长度

       mov ax, 01301h            ; AH = 13,  AL = 01h

       mov bx, 000ch              ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)

       mov dl, 0

       int   10h                ; 10h 号中断

       ret

BootMessage:         db    "Hello, OS world!"

 

; fill floppy

    times (2 * 18 * 80 * 512 - ($ - $$)) db 0

 

 

软盘,INT 13HIMG文件

1:软盘

 软盘是以扇区为基本单位来进行操作的,每扇区512字节,共2880个扇区,空间大小为1.44M.

 2880个扇区又可以用(磁头、磁道、扇区)这三个参数来描述。我们简单记(磁头、磁道、扇区)为(x,y,z),那么

  X的取值范围是:0—1

  Y的取值范围是:0--79

  Z的取值范围是:1—18

也就是说软盘有2磁头、每磁头有80磁道、每磁道有18扇区,2880个扇区(2880=2*80*18)。

如果把2880个扇区从0开始编号,一直到2879结束,那么

编号为i的扇区和(X,Y,Z)的换算公式为:i=80*18*x+18*y+z-1

2:INT 13H

  INT13H是磁盘的BOIS中断,对于读写扇区操作,中断的完整调用参数如下:

  AL=扇区数    

  AH=中断子功能号     ;2=读扇区,3=写扇区

  CL67,CH = 磁道号  ;每磁头最多可以有2^10=1024个磁道

  CL的低6   =  扇区号  ;每磁道最多可以有2^6=64个扇区

  DH = 磁头号     ;最多可以有256个磁头

  DL = 驱动器号     ;0=软盘,80H=硬盘

  ES:BX=数据缓冲区的地址

其他:

1).

  对于软盘来说,实际的INT 13HDL=0,而CLCHDH的取值范围也不可能取到上面的数值,根据1:中的数据,有

CL的取值范围是:1--18

CH的取值范围是:0-79

DH 的取值范围是:0—1

如果软盘的CLCHDH取值超过了范围,中断调用出错。

AL的取值也不是任意的,一次调用INT13H进行读写扇区的只可以在一个磁道内的扇区进行。如果超出了一个磁道,必须要更新INT13H的中寄存器,重复调用INT13H

对于软盘来说 AL必须要小于19-CL

下面是一个从软盘的(x,y,z)扇区中连续读出n个扇区的内容到缓冲区BUFFER中的代码片段代码使用了一些80386的指令和MASM6.0才支持的伪指令)

 MOV  AX,DS

 MOV  ES,AX

MOV  BX,OFFSET

MOV   BP,  n 

MOV CLz

MOV CHy

MOV DL

MOV DHx

.WHILE  BP  ;bp记录的是还没有进行读操作的扇区数量

;WHILE伪指令,和高级语言的WHILE一样理解就可以了,下面的。IF也一样

 ;AL的取值进行计算

 MOV AL,19

    SUB AL,CL ;最多可以读19-CL个扇区

    XOR AH,AH

 .IF AX>BP  

      MOV AX,BP

   XOR BP,BP 

    .ELSE  

  SUB BP,AX ;更新BP

       .ENDIF    

  MOV AH,2

INT 13H   ;读扇区

 ;更新CLCHDH

MOV CL,1  

.IF  CH==79 

   INC DH

   XOR CH,CH

  .ELSE

      INC CH

  .ENDIF

  XOR AH,AH

  SHL AL,9 ;AX=AL*512,等于已经处理的字节数

     ;SHL AL,9SHL AX4都是80386+才支持的指令

        SHR AX,4   ;AX=AX/16

  ADD ES,AX  ;更新ESBX,这里是更新了ES,也可以更新BX

 .endw

2).

  INT13H只理论上最多处理 2^24个扇区*512字节/扇区=8G的磁盘空间,这对现在的硬盘来说,是远远不够的,于是后来对INT13H进行了扩展,用AH=42HAH=43H分别对大硬盘进行操作,这里就不详细讨论了。

3:IMG文件

 IMG文件是软盘的镜像文件,文件大小也是1.44M,它和软盘是一种线性的对应关系。

软盘上一个编号为(x,y,z)512字节的扇区,对应IMG文件中的以2400H*x+4800H*y+(z-1)*512为基址的512个字节(注意,2400H,4800H16进制数)。

IMG文件的字节和软盘的扇区对应关系也可以如下图所示(注意那些是十进制,那些是16进制)

 

对于扩展INT 13中断,参数如下:

中断号 功能                       调用寄存器 返回寄存器       备注

INT 13

AH=41H 检测扩展中断功能是否安装 AH = 41h

                 BX=55AAh

                DL = 驱动器号(80hFFH)

                 失败:AH=1

                 CF置位

                 成功:AH=版本号

                 CF=0 BX=AA55H 

INT 13

AH=42H 磁盘扩展读操作              AH = 42H

                    DL = 驱动器号

                    DS:SI=指向LBA地址包的指针 失败:AH=错误号

                    CF置位

                    成功:AH=0

                    CF=0

  地址包定义:

                    偏移 大小 描述

                    00H 字节 地址包大小

                    01H 字节 保留(为0

                    02H      传输包个数

                    04H 双字 指向数据指针

                    08H 4     起始地址

                    其中LBA=((柱面*磁头/柱面+磁头)*扇区/柱面)+扇区-1

INT 13

AH=43H 磁盘扩展写操作               AH=43H

                         AL=写标志

                      DL = 驱动器号

                      DS:SI=指向LBA地址包的指针 失败:AH=错误号

                                     CF置位

                               成功:AH=0

                                                     CF =0 同上

INT 13

AH=48H 获取磁盘参数 AH=48H

                                     DL=驱动器号

                                      DS:SI=指向保存参数缓冲区的指针

                                       失败:AH=错误号

                           CF置位

                                       成功:AH=0

                           CF=0

 参数缓冲区定义:

                    偏移 大小 描述

                    00H  缓冲区大小

                    02H  信息标志位

                    04H 双字 物理柱面数

                    08H 双字 物理磁头数

                    0CH 双字 物理每柱扇区数

                    10H 4 扇区总数

                    18H  每扇区字节数

 

本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接,严禁用于任何商业用途。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net 
阅读(1018) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~