我有一个磁盘,每个磁道有63个扇区。 (根据我的观察,我认为)我想使用int 13h在16位引导加载程序上读取扇区。例如,如果我想读取扇区号63,则可以执行以下操作:
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
上面的代码按预期工作。
现在,我想读取扇区64。我相信它将是圆柱0,磁头1,扇区1。我使用:
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也不起作用
您先前的问题和评论旨在在硬盘驱动器上使用CHS(气缸,气缸盖,扇区)寻址。正如我之前提到的,硬盘驱动器最好使用Int 13h/AH=42H来避免完全使用CHS,而改用LBA(逻辑块地址)。逻辑块地址从0开始,一直到驱动器上的总扇区数减去1。处理LBA更加容易。
使用依赖CHS的BIOS功能的缺点是扇区固定为512字节。使用LBA assist BIOS translation(受BOCHS和QEMU支持),您可以从驱动器读取的最大扇区数为1024 * 255 * 63 = 16450560扇区或16450560 * 512 =8422686720(〜7.844GiB /〜8.423GB)。通过CHS寻址,您将无法阅读更多内容。
您可以使用我先前在related answer中描述的公式转换LBA:
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):
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检索这些值。在related answer中,我提供了示例代码,该示例代码使用Int 13h/AH=8h获取SPT和Heads并从32位LBA计算CHS,然后使用这些值通过Int 13h/AH=2h
读取扇区。以下C程序带有3个参数。 HEADS,SPT和LBA使用上述公式来计算CHS:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
unsigned int heads;
unsigned int spt; /* sectors per track */
unsigned char h; /* Head */
unsigned char c; /* Cylinder */
unsigned char s; /* Sector */
unsigned int lba;
if (argc != 4) {
fprintf (stderr, "Usage: HEADS SPT LBA\n");
return 1;
}
heads = atoi(argv[1]);
spt = atoi(argv[2]);
lba = atoi(argv[3]);
/* Proper calculation */
c = (lba / spt) / heads;
h = (lba / spt) % heads;
s = (lba % spt) + 1;
printf ("LBA = %4d is CHS = (%2d, %2d, %2d)\n", lba, c, h, s);
return 0;
}
如果您要从LBA计算CHS,此程序将很方便。在您的情况下,您想知道磁盘上第64个扇区的CHS值。 LBA基于0,因此LBA 64-1 = 63。在您的注释/聊天中,BIOS报告SPT = 36和Heads = 16。如果使用以下命令编译并运行上述程序:
gcc lbatochs.c -o lbatochs
./lbatochs 16 36 63
结果应该是:
LBA = 63是CHS =(0,1,28)
因此,您需要使用Cylinder = 0,Head = 1和Sector = 28设置对Int 13/AH=2h的调用,以读取驱动器上的第64个扇区(LBA = 63)。