关于INT13H函数对U盘的读写

在《30天自制操作系统》中,作者使用软盘作为操作系统存储介质进行操作系统的编写讲解。但目前计算机设备都已基本放弃软盘支持,虽然依然可以在虚拟机上进行模拟练习,始终还是希望有一个可以真正能在物理设备上驱动安装的系统。

目前常用的移动介质基本都是U盘,所以我开始尝试用U盘开始学习。但在进行存储读写时,就出现了问题。因为U盘的存储结构和软盘是有区别的。而且,现在多数都使用FAT32格式,那么对于MBR中BPB(BIOS Parameter Block)的结构也存在差异。

目前对于磁盘的读写有2种方式,一种是CHS寻址模式,一种是LBA寻址模式。CHS方式更多的是基于最初的磁盘结构,就是柱面+磁头+扇区的读写方式。书中作者对软盘的读写就是采用的这种方式。LBA是一种基于逻辑地址块的寻址模式。这种模式隐藏了存储器底层的一些细节,比如对于柱面、磁头、扇区等的了解。因而也是一种更为通用的磁盘读写模式。虽然CHS和LBA的寻址基本单位都是扇区,但CHS需要3个参数同时确定一个扇区,而LBA将所有的扇区进行逻辑上的线性排列,从而能够进行线性查询。

BOIS中的INT13H函数支持这两种寻址模式。

在查找资料的过程中,我没有查找到利用INT13H函数用CHS模式对U盘进行读写的示例,因为我也是初学者,对于这方面的知识也不全面,所以,我也不确定在CHS模式是否可以。但LBA模式是一定可以的。

LBA模式在读写硬盘上虽然较为CHS模式简单,因为它是线性寻址的。但在INT13H函数中,需要提前设置一个地址数据结构,用于存储一些读取信息,比如读取的内存地址、扇区数、其实LBA块等。该数据结构的构成格式如下:

偏移(字节)

大小(字节)

说明

0

1

该数据结构的大小,通常为16字节

1

1

通常为0,意义不明

2

2

传输的扇区数(在某些BIOS中最大为127)。

4

4

内存地址(2字节的段地址:2字节的偏移地址)。

8

4

起始LBA

12

4

用于对大容量存储设备的读取

 

该模式下的INT13H调用过程:

l  首先在磁盘地址数据结构体中设置正确的值。

l  设置DS:SI地址数据结构在内存中的地址

l  读出数据到内存:AH=0x42,写入内存数据到磁盘AH=0x43

l  DL=驱动器编号

l  调用INT    0x13

在读取的过程中出现错误的话,进位标志(carry flag)会被置1。执行成功的话,AH置0


实例:

entry:
	mov     ax,cs	;初始化寄存器
	mov	ds,ax
	mov	ds,ax
	mov	es,ax
	
	mov	ah,0x42
	mov	dl,0x80
	mov	si,packet
	int     0x13
	
	jc	error
	
        ;将写入的内存地址后移512字节
        ;以下是将地址数据结构中的起始LBA后移1块继续写入下一个扇区

	;将packet的内存偏移512字节
	mov	ax,[bufferoff]
	mov	bx,bufferoff
	add	ax,0x0200
	mov	[bx],ax

	;将起始LBA加1,以读取下一个扇区
	mov	ax,[blockNum]
	mov	bx,blockNum
	add	ax,1
	mov	[bx],ax
	
	cmp	ax,5	;连续读取4个扇区
	je 	finish
	
	jmp	entry
;地址数据结构体
packet:
packet_size:     db	10h             ;packet大小,16个字节
reserved:	 db     0
count:		 dw	1		;读1个扇区
bufferoff:       dw	0x0820          ;读到内存0x0820处,偏移地址
bufferseg:	 dw	0		;段地址
blockNum:	 dd	1               ;起始LBA块
		 dd     0

error:
finish:

对于以上程序,也可以在packet的count中一次性设置需要写入的扇区数。但为了测试连续写入,所以我每次只写入一个扇区。

详细的可参见:

http://wiki.osdev.org/ATA_in_x86_RealMode_(BIOS)

http://www.cnblogs.com/zeng2013/p/3637864.html


展开阅读全文

没有更多推荐了,返回首页