使用BIOS int 13h访问不同磁头中的扇区 [英] Using BIOS int 13h to access sectors in different heads

查看:129
本文介绍了使用BIOS int 13h访问不同磁头中的扇区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个磁盘,每个磁道有63个扇区. (根据我的观察,我认为) 我想使用int 13h在16位引导加载程序上读取扇区. 例如,如果我想读取扇区号63,则可以执行以下操作:

I have a disk with 63 sectors per track. (I assume, based on my observations) I want to read sectors on a 16 bit bootloader using int 13h. For example, if I want to read sector number 63, I would do the following:

mov dl,0x80;Drive number
mov dh,0 ;This is head number/platter number
mov ch,0  ;This is cylinder number
mov cl,63 ;Sector number
mov ah,0x02 ;interrupt function
mov al,1  ;Number of sectors to be read
xor bx,bx 
mov es,bx ;Making es=0
mov bx,0x8000 ;Any random buffer address
int 0x13

上面的代码按预期工作.

The above code works as expected.

现在,我想读取扇区64.我相信它将是圆柱0,磁头1,扇区1. 我使用:

Now I want to read sector 64. I believe that it would be cylinder 0, head 1, sector 1. I use:

mov dl,0x80;Drive number
mov dh,1 ;This is head number/platter number
mov ch,0  ;This is cylinder number
mov cl,1 ;Sector number
mov ah,0x02 ;interrupt function
mov al,1  ;Number of sectors to be read
xor bx,bx 
mov es,bx ;Making es=0
mov bx,0x8000 ;Any random buffer address
int 0x13

这不起作用.

P.S.我认为每个磁道的扇区数为63的原因是因为简单地设置cl = 64也不起作用

P.S. The reason I believe that the number of sectors per track is 63 is because simply setting cl = 64 also does not work

推荐答案

TL; DR :驱动器(或仿真器或虚拟机中的驱动器映像)的大小可能会影响磁头的数量, BIOS报告的每磁道的柱面数和扇区数(SPT).通过查询BIOS可能获得的值可能会因大小而有所不同,并且可能因计算机而异,并且

TL;DR: The size of a drive (or drive image in emulators or virtual machines) may impact the number of heads, cylinders and sectors per track (SPT) reported by the BIOS. The values you may get by querying the BIOS may differ depending on the size and may vary from computer to computer and the CHS translation scheme being used by the BIOS.

如果您有BIOS报告驱动器具有16个磁头和63个SPT,则CHS(0,1,1)应该是驱动器上的第64个扇区.但是,如果BIOS报告16磁头和36 SPT,则第64个扇区为CHS(0,1,28).如果使用带有CHS寻址的硬盘驱动器,则在引导加载程序运行时,始终向BIOS查询磁头和SPT的数量,并计算逻辑块地址(LBA).强烈建议不要将柱面数,磁头数和SPT值硬编码到引导加载程序中.

If you have a BIOS that reports a drive as having 16 heads and 63 SPT then a CHS(0, 1, 1) should be the 64th sector on the drive. If however the BIOS reports 16 heads and 36 SPT then the 64th sector is CHS(0, 1, 28). If using a hard drive with CHS addressing always query the BIOS for the number of heads and SPT and compute logical block addresses (LBA) when your bootloader runs. It is highly recommended to not hard code the number of cylinders, number of heads, and SPT value into a bootloader.

不要使用0x80作为驱动器号,而应使用BIOS传递给引导加载程序的 DL 中的值.使用该值,而不是对启动驱动器号进行硬编码.我有一些常规Bootloader提示,涵盖了进行传统Bootloader开发时可能需要考虑的内容和其他事项.

Rather than use 0x80 for a drive number, use the value in DL that the BIOS passes to your bootloader. Use that value rather than hard coding the boot drive number. I have some General Bootloader Tips that covers that and other things you may wish to consider in doing legacy bootloader development.

磁头,磁头,扇区(CHS)寻址来自在圆形磁盘(或软盘)上使用磁性介质的介质. Wikipedia在关于CHS的主题上有很好的文章.物理上描述CHS的图:

Cylinder, Head, Sector (CHS) addressing came about from media that used magnetic media on round platters (or floppy disk). Wikipedia has a good article on the subject of CHS. A diagram depicting CHS in a physical sense:

图片来源Wikipedia

磁道是同心圆(在盘片的单侧),分为多个部分,称为扇区.驱动头读取盘片一侧的轨道.需要2个头才能进入物理拼盘的两侧.圆柱体是媒体上所有轨道的显示,当它们一个出现在另一个之上时.

A track is a concentric circle (on a single side of a platter) that is divided into sections called a sector. A drive head reads the tracks on one side of a platter. 2 heads are required to access both sides of a physical platter. A cylinder is the collection of all the tracks on the media as they appear one on top of another.

一段时间后,柱面,扇区和磁头的概念不再与物理实现相匹配,但是出于兼容性的考虑,CHS寻址仍用于访问设备上的数据. 逻辑块寻址(LBA)最终已被CHS淘汰,它是在媒体上显示为硬盘驱动器到BIOS. CHS寻址仍在将自身作为软盘介质呈现给BIOS的设备上使用.不是所有的BIOS都支持LBA对软盘介质的访问,在这种情况下,CHS寻址仍然是首选的机制.

After time the concept of cylinders, sectors, and heads no longer matched the physical implementation however CHS addressing was still used to access data on a device for compatibility. Logical Block Addressing (LBA) eventually obsoleted CHS and is the preferred method on media that appears as a hard drive to the BIOS. CHS addressing is still used on devices that present themselves as floppy disk media to the BIOS. LBA access to floppy media is not supported by all BIOSes, and CHS addressing is still the preferred mechanism in that case.

您先前的问题和评论旨在使用硬盘驱动器上的CHS寻址.如前所述,对于硬盘驱动器,首选使用 Int 13h/AH = 42H 避免完全使用CHS,而改用LBA.逻辑块地址从0开始,一直到驱动器上的总扇区数减去1.处理LBA更加容易.

Your previous question and comments are intent on using CHS addressing on a hard drive. As I previously mentioned it is preferred with hard drives to use Int 13h/AH=42H to avoid using CHS at all and using LBA instead. A logical block address starts at 0 and goes up to the total sector count on the drive minus 1. Dealing with an LBA is much easier.

使用依赖CHS的BIOS功能的缺点是扇区固定为512字节.使用 LBA辅助BIOS转换(由BOCHS和QEMU支持)的最大数量您可以从驱动器读取的扇区为1024 * 255 * 63 = 16450560扇区或16450560 * 512 = 8422686720(〜7.844GiB/〜8.423GB).使用CHS寻址将无法阅读更多内容.

The disadvantages of using BIOS functions that rely on CHS are that sectors are fixed to 512 bytes. With LBA assist BIOS translation (Supported by BOCHS and QEMU) the maximum number of sectors you can read from a drive is 1024*255*63=16450560 sectors or 16450560*512=‭8422686720‬ (~7.844GiB/~8.423GB). You won't be able to read beyond that with CHS addressing.

您可以使用我先前在相关答案中描述的公式来转换LBA :

You can convert an LBA using a formula I have previously described in a related answer:

LBA is the logical block address
HPC is the maximum number of heads per cylinder (reported by 
    disk drive, typically 16 for 28-bit LBA)
SPT is the maximum number of sectors per track (reported by
    disk drive, typically 63 for 28-bit LBA)

LBA addresses can be mapped to CHS tuples with the following formula 
    ("mod" is the modulo operation, i.e. the remainder, and "÷" is 
    integer division, i.e. the quotient of the division where any 
    fractional part is discarded):

C = (LBA ÷ SPT) ÷ HPC
H = (LBA ÷ SPT) mod HPC
S = (LBA mod SPT) + 1

where C, H and S are the cylinder number, the head number, and the sector number

您可以使用以下方法进行反向计算(从CHS到LBA):

You can do the calculation in the reverse direction (CHS to LBA) using:

CHS tuples can be mapped to LBA address with the following formula:

LBA = (C × HPC + H) × SPT + (S - 1)

为了计算磁盘上给定LBA的CHS,您需要知道每磁道扇区数(SPT)和磁头数. Int 13h/AH = 8h 可用于从BIOS检索这些值.在引导程序运行时运行.在相关答案中,我提供了使用整数13h/AH = 2h

In order to compute CHS for a given LBA on the disk you need to know the Sectors Per Track (SPT) and the number of heads. Int 13h/AH=8h can be used to retrieve these values from the BIOS at runtime in the bootloader. In a related answer I provide example code that uses Int 13h/AH=8h to get SPT and Heads and computes CHS from a 32-bit LBA and then use those values to read a sector with Int 13h/AH=2h

以下 C 程序带有3个参数. HEADS,SPT和LBA使用上述公式来计算CHS:

The following C program takes 3 arguments. HEADS, SPT, and LBA to compute CHS using the formula above:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    unsigned int heads;
    unsigned int spt; /* sectors per track */

    unsigned int h;  /* Head */
    unsigned int c;  /* Cylinder */
    unsigned int s;  /* Sector */

    unsigned int lba;

    if (argc != 4) {
        fprintf (stderr, "Usage: HEADS SPT LBA\n");
        return 1;
    }

    heads = atoi(argv[1]);
    if (heads > 255 || heads < 1) {
        fprintf (stderr, "Error: HEADS must be <= 255 and >= 1\n");
        return 1;
    }

    spt = atoi(argv[2]);
    if (spt > 63 || spt < 1) {
        fprintf (stderr, "Error: SPT must be <= 63 and >= 1\n");
        return 1;
    }

    lba = atoi(argv[3]);

    /* Proper calculation */
    c = (lba / spt) / heads;
    h = (lba / spt) % heads;
    s = (lba % spt) + 1;

    printf ("SPT = %u, Heads = %u\n", spt, heads);
    printf ("LBA = %u is CHS = (%u, %u, %u)\n\n", lba, c, h, s);
    if (c >= 1024)
        printf ("Can't use CHS because %u cylinders >= 1024, use LBA!\n", c);
    else
        printf ("DH = 0x%02X, CH = 0x%02X, CL = 0x%02X\n",
                h, c & 0xff, s | ((c >> 2) & 0xc0));

    return 0;
}

如果要从LBA计算CHS,此程序可能会很方便.在您的情况下,您想知道磁盘上第64个扇区的CHS值. LBA基于0,因此LBA 64-1 = 63.在您的注释/聊天中,BIOS报告SPT = 36和Heads = 16.如果您使用以下命令编译并运行上述程序:

This program can be convenient if you want to compute CHS from an LBA. In your case you want to know the CHS values for the 64th sector on the disk. LBA's are 0 based so that is LBA 64-1=63. In your comments/chat the BIOS is reporting SPT=36 and Heads=16. If you compile and run the program above with:

gcc lbatochs.c -o lbatochs
./lbatochs 16 36 63

结果应为:

SPT = 36, Heads = 16
LBA = 63 is CHS = (0, 1, 28)

DH = 0x01, CH = 0x00, CL = 0x1C

对于BIOS报告具有SPT 63和16磁头的驱动器,对于LBA 63,结果应如下所示:

For a drive that the BIOS reports with SPT 63 and 16 heads the results should look like this for LBA 63:

./lbatochs 16 63 63

SPT = 63, Heads = 16
LBA = 63 is CHS = (0, 1, 1)

DH = 0x01, CH = 0x00, CL = 0x01

这篇关于使用BIOS int 13h访问不同磁头中的扇区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆