【问题标题】:Is there any way to read the kernel placed on head = 1 with int 13h?有没有办法用int 13h读取放在head = 1上的内核?
【发布时间】:2019-10-26 07:43:13
【问题描述】:

当我按下回车键时,我的引导加载程序必须进入内核,但它没有反应。 Bootloader位于第一个磁道的第一个扇区,磁头-0,但内核的地址是:扇区3,磁道-0,磁头1。

我什至将内核放在第一条轨道的第 5 个扇区。我已经有从软盘读取和写入的函数,尝试从位于我的内核的头 1 读取,并且它读取正确。但是当我在引导加载程序中放入相应的磁头、扇区和磁道时,在读取int 13h/ah=02h 时它什么也没做。

引导加载程序

readingProcess:
        xor AX, AX     
    mov DS, AX      
    mov BX, 0060h   
    cli           
    mov ss,bx      
    mov sp,ax    
    sti           
    cld

    mov AH, 02h   
    mov AL, 25          
    mov CH, 0           
    mov CL, 3           
    mov DL, 0           
    mov DH, 1               

    mov BX, 0060h
    mov ES, BX
    xor BX, BX

    int 13h

    ;go to kernel
    jmp 0060h:0000h
ret

所以,现在我真的不明白它是如何工作的,因为当我尝试向软盘写入磁头 1 时,它应该几乎在我的 .img 文件的中间,但它出现在我的开头的文件。我认为一定有一个公式可以帮助我找到正确的轨道和部门。

【问题讨论】:

  • 需要检查的几件事:您将堆栈设置为 0060:0000。我认为这意味着您的堆栈中没有空间,因此int 13h 指令将引发异常,然后出现双重故障并停止。您没有检查来自int 13h 的返回值来检查错误。您正在尝试读取 25 个扇区,从扇区 3 开始。IIRC,只有在您尝试读取的轨道上至少有 27 个扇区时才会起作用。
  • @1201ProgramAlarm :他已将堆栈设置为 0x0060:0x0000,这没关系。在 16 位实模式下 - 在第一次推送时 SP 将减 2,这会将 SP 包装到 0x0060:0xfffe。
  • 你如何测试这个?在真实硬件上还是在模拟器/虚拟机中?如果是模拟器或虚拟机,是哪一个?如果在真实硬件上,您是作为 USB 媒体启动的吗?
  • 在这个答案中有一些关于 LBA(逻辑块地址)到 CHS 计算的信息:stackoverflow.com/questions/45434899/…。 LBA 是一个介于 0 和磁盘上扇区之间的数字。如果您知道要读取的数据的 LBA 位置,您可以将其转换为 CHS,您是否知道每个媒体轨道的磁头和扇区数
  • 避免在读取时越过磁道边界的最简单方法是一次读取/写入一个扇区。所以不是读取 25 个扇区,而是一次读取 25 个扇区 1。读取 1 个扇区永远不能跨越 Track 边界,否则您需要计算当前磁道上剩余的扇区数且不超过该数量,并且如果需要将磁盘读取拆分为多个读取。

标签: assembly nasm x86-16 bootloader bios


【解决方案1】:

查看您的代码后,看来这完全是使用right formula 获取磁盘映像文件中给定偏移量的磁道(圆柱)、磁头和扇区值的问题。您想为 Int 13h/ah=2(磁盘读取)使用正确的值。

根据我之前的回答,我给出的公式为:

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

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

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

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 ÷ (HPC × SPT)
    H = (LBA ÷ SPT) mod HPC
    S = (LBA mod SPT) + 1

有关驱动器寻址的更多信息,请参阅此 Wikipedia article

对于 1.44MiB 的软盘,总共有 2880 个扇区,HPC(Heads per cylinder) 为 2,SPT(Sectors Per Track 为 18),每个扇区为 512 字节。您需要的是 LBA。 LBA 只是您写入内核的偏移量(以字节为单位)除以 512。在您的 Appender 程序中,您将内核的副本放置在偏移量 738304 处。LBA=738304/512=1442。

您只需将 LBA 1442 转换为 CHS 并将这些数字插入代码。

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

 We know:
    LBA = 1442
    HPC = 2
    SPT = 18        

做替换得到:

C = 1442 ÷ (2 × 18)
H = (1442 ÷ 18) mod 2
S = (1442 mod 18) + 1

÷ 表示整数除法并丢弃余数(分数)。 mod 表示除法保留余数,全部丢弃。

C = 1442 ÷ (2 × 18) = 40.0555556 = 40
H = (1442 ÷ 18) mod 2 = 80 mod 2 = 0 (80 mod 2 = 40 remainder 0)
S = (1442 mod 18) + 1 = (2) + 1 = 3 (1442 mod 18 = 80 remainder 2)

我们现在知道对于 LBA 1442,Cylinder(Track) = 40, Head = 0, Sector = 3。您的代码将在 Int 13h/AH=2 BIOS 调用中使用这些值。您将在 DH 中放置 40,在 CH 中放置 0,在 CL 中放置 3。

您似乎还在磁盘映像中的偏移量 2048 处放置了一份内核副本。偏移量 2048 是 4 (2048/512) 的 LBA 使用上面的公式和值,您会得到 Cylinder(Track) = 0,Head = 0,Sector = 5。您将 0 放在 DHCH 中为 0,CL 中为 5。

特别说明:只有扇区号从 1 开始。圆柱(轨道)和磁头从 0 开始。


如果给定 Cylinder(Track)、Head 和 Sector,并且需要知道磁盘上对应的 LBA,公式为:

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

如果您的 CHS 为 (40, 0, 3),驱动器几何尺寸为 1.44MiB(HPC=2 和 SPT=18),则 LBA=(40*2+0)*1​​8+(3-1)=1442。 1442*512=738304 将是该扇区的磁盘偏移量。

如果您的 CHS 为 (0, 0, 5),驱动器几何尺寸为 1.44MiB(HPC=2 和 SPT=18),则 LBA=(0*2+0)*1​​8+(5-1)=4。 4*512=2048 将是该扇区的磁盘偏移量。

这两个计算与本答案第一部分计算的结果相反。

【讨论】:

  • 先生,非常非常非常非常非常感谢您。效果很好,你是我的英雄!!再来一次,谢谢你,抱歉问了太多问题。
  • @eLyyLe :很高兴你成功了。请考虑接受它作为答案(并且足够好)。更多关于accepting an answer 的方式和原因可以在这篇文章中找到::meta.stackexchange.com/questions/5234/…。赞成和接受答案是有区别的。当人们将来查询时,正确接受答案会将该问题标记为已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-16
  • 2013-02-01
  • 1970-01-01
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多