X86 Phoenix BIOS跳过MBR代码,实际的BIOS标准是什么?

X86 Phoenix BIOS跳过MBR代码,实际的BIOS标准是什么?,x86,usb,phoenix,bios,mbr,X86,Usb,Phoenix,Bios,Mbr,我想学习汇编程序使用超最小裸代码,让任何x86兼容的机器在开机时在屏幕上显示硬编码文本。 我关心与x86/IBM机器的完全兼容性 我学习了一些简单引导代码的教程,但不幸的是,我无法从笔记本电脑的USB接口上运行它们。就好像我的笔记本根本没有触及MBR代码一样。 我花了两周的时间阅读了大量的文章,结果一无所获。我学到了很多关于BIOS参数块、分区条目和UEFI的知识 我的笔记本电脑使用可引导FreeDOS USB正确引导。 这是我的FreeDOS USB与MBR的第一个扇区: 我试着用UEFI从

我想学习汇编程序使用超最小裸代码,让任何x86兼容的机器在开机时在屏幕上显示硬编码文本。 我关心与x86/IBM机器的完全兼容性

我学习了一些简单引导代码的教程,但不幸的是,我无法从笔记本电脑的USB接口上运行它们。就好像我的笔记本根本没有触及MBR代码一样。 我花了两周的时间阅读了大量的文章,结果一无所获。我学到了很多关于BIOS参数块、分区条目和UEFI的知识

我的笔记本电脑使用可引导FreeDOS USB正确引导。 这是我的FreeDOS USB与MBR的第一个扇区:

我试着用UEFI从桌面电脑启动它,它成功了。 我试着用Phoenix BIOS从笔记本上启动它,它成功了

然后我擦去了所有的引导说明:

我试着用UEFI从同一台台式计算机上启动它,但正如预期的那样失败了。 我试着用Phoenix BIOS从笔记本上启动它,它成功了。我发誓

我想知道为什么会有一个BIOS,它自己处理事情,跳过MBR指令,如果有更多类似的,我在哪里可以找到它们的文档,这样我就可以使我的引导代码与所有BIOS完全兼容

我笔记本电脑的BIOS版本是1.08,EC版本是1.07。
我不想更新它。如果FreeDOS可以很好地引导它,那么我希望我的引导代码也可以很好地引导它。

这个答案基于经验和有根据的猜测。如果没有实际的硬件,测试是相当困难的。我假设OP正在将引导扇区写入MBR,而不是VBR


多年来,人们创造了一些既愚蠢又聪明的生物传感器(有些太聪明了)。有些人试图根据BIOS参数块和/或具有可引导分区的分区表来区分可能是软盘驱动器或硬盘驱动器的介质。不幸的是,这不是标准化的,许多BIOS制造商只针对Windows分区的磁盘测试他们的代码

一些认为看到有效分区表的BIOS将采用HDD模拟,并尝试从活动分区加载卷引导记录(VBR),而不是在MBR上执行代码。我怀疑这是机器上的情况,尽管清除了代码并保留了分区表,但它似乎仍在引导。执行的代码可能直接来自VBR

如果使用充当硬盘驱动器(而不是软盘)的设备,则可以使用分区表创建MBR,其中唯一活动分区从驱动器的开头开始(CHS=0,0,1或LBA=0);标记为可引导;并且具有非零分区类型。如果您遇到一台打算直接加载VBR的机器,那么此方法将诱使它将MBR作为VBR加载

在您似乎要测试的机器上,作为HDD介质在USB上引导的示例代码可能如下所示:

bits 16
org 0x7c00

boot_start:
    xor ax, ax                  ; DS=0 since we use ORG 0x7c00. 0x0000<<4+0x7c00=0x7c00
    mov ds, ax
    mov es, ax

    ; If you will be reading data into memory outside of 0x7c00 to 0x7dff
    ; then you want to set the stack SS:SP - uncomment these lines
    ; mov ss, ax                ; Stack at 0x0000:0x7c00
    ; mov sp, 0x7c00            ;     Just below bootloader

    cld                         ; Forward movement of string instructions
                                ;     (MOVSB, SCASB, etc)

    mov si, HelloWorldMsg       ; Print hello world
    call print_string

end_loop:                       ; Loop forever to terminate
    hlt
    jmp end_loop

; Function: print_string
;           Display a string to the console on display page 0
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string:
    mov ah, 0x0e                ; BIOS tty Print
    xor bx, bx                  ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 0x10                    ; print character
.getch:
    lodsb                       ; Get character from string
    test al,al                  ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character
.end:
    ret

HelloWorldMsg:   db "Hello, world!", 0x0d, 0x0a, 0

times 446-($-$$) db 0   ; Pad with 0s up until first partition entry
part1_entry:
db 0x80                 ; 0x80 = Active boot partition, 0x00=inactive
db 0x00, 0x01, 0x00     ; CHS of first absolute sector (MBR) of hard drive
                        ;     Head=0, Sector=1, Cylinder=0
db 0x0c                 ; Partition type (has to be non-zero)
                        ;     0x0c = Win 95 FAT32 (LBA)
db 0x00, 0x01, 0x00     ; CHS of last absolute sector (MBR) of hard drive
                        ;     Head=0, Sector=1, Cylinder=0
                        ;     We are effectively saying Size of partition is 1 sector
dd 0x0                  ; LBA of first absolute sector (0=MBR)
dd 0x1                  ; Number of sectors in partition. We set it to 1 but if you
                        ;     wish you could set it to the number of sectors on the disk

times 510-($-$$) db 0   ; Pad remainder of boot sector up to boot signature. This zeroes
                        ;     partition entries 2,3,4 effectively making them inactive

dw 0xAA55               ; The standard PC boot signature after partition table
如果成功放置在介质上,则此代码应打印:

你好,世界


根据您所说的,我假设您正在使用硬盘驱动器模拟(HDD)而不是软盘模拟(FDD)引导此USB。使用HDD USB模拟,一些BIOS将实际从第一个扇区(MBR)读取分区表,找到一个活动项,然后自动加载卷的第一个扇区(VBR)并开始运行它,而不是MBR中的代码。对于Freedos,分区的第一个扇区很可能是实际运行的代码。这只是一个猜测。不同制造商的生物传感器工作原理不同,不幸的是,这种情况可能有点随意。增加通过USB HDD引导并让代码在MBR中运行的机会的一种技术是实际创建一个分区表,其中活动分区指向MBR本身,而不是卷引导记录(VBR)。您好@MichaelPetch,您的假设是正确的。BIOS只能模拟USB硬盘,它是不可配置的。我还猜测VBR是直接执行的,并考虑通过跳转到MBR来修复它,以最大限度地提高BIOS之间的兼容性。但是现在我想知道是否有一本书或一篇文章列出了所有已知的BIOS引导行为,这样我就可以确保我的代码不会在我插入的下一台机器上崩溃。FreeDOS开发人员是如何知道这些行为的存在,从而形成这样一个解决方案的?或者你认为这仅仅是巧合,因为首先加载VBR是一个标准过程?不,这不是一个完整的地方记录的,而是基于互联网上传播的信息。在他们的维基页面和论坛上有一些信息,但也不是全部整合在一个地方。这就是为什么很多人使用像GRUB这样的引导加载程序来处理所有这些问题。嗨,Michael,我想让你知道我已经通过将汇编代码写入VBR来运行我的汇编代码了。但事情并不是那么简单。事实上,它不是那么简单的原因与上面的代码在我的笔记本上仍然无法工作的原因相同。原因是:我的BIOS不仅检查有效的分区表,它还加载第一个活动分区的第一个扇区,并检查该分区的有效FS标头(太聪明了>:C)。只有这样,它才能在VBR上运行引导代码(我在这里编写了我的程序)Src:如果您感兴趣,我的程序必须加载到内存地址0x7C5A(如果我记得很清楚的话),这意味着我必须先写“org 0x7C5A”。然后我必须在usb VBR上的FS头之后复制编译好的二进制文件,就是这样。让它运行起来D@AntonioDelasCarreras听起来您的BIOS还需要一个BIOS参数块和一个分区表(如果您尝试使用自引用方法)。这是一个真正的可能性,但我想尝试一些东西,通过消除的过程,以改善答案。你能从这里下载这两个文件吗:。这个
nasm -f bin boot.asm -o boot.bin