首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MBR从DOS启动

MBR从DOS启动
EN

Stack Overflow用户
提问于 2010-04-15 00:38:03
回答 2查看 1.3K关注 0票数 6

对于一个项目,我想直接从DOS调用第一个硬盘上的MBR。我已经写了一个小的汇编程序,它在0:7c00h加载内存中的MBR,并跳转到它。我已经把我的实用程序放在(DOS)可启动软盘上了。我尝试引导的磁盘(HD0,0x80)上有一个TrueCrypt引导加载程序。当我在此设置中运行该工具时,它会显示TrueCrypt屏幕,但在输入密码后,它会使系统崩溃。当我在一台普通的WinXP机器上运行我的小工具(w00t.com)时,它似乎马上就崩溃了。

显然,我忘记了BIOS通常会做的一些重要的事情,我猜是一些微不足道的事情。有更好的裸机DOS和BIOS经验的人能帮我吗?

下面是我的代码:

代码语言:javascript
复制
.MODEL tiny
.386
_TEXT SEGMENT USE16

INCLUDE BootDefs.i

ORG 100h

start:
    ; http://vxheavens.com/lib/vbw05.html
    ; Before DOS has booted the BIOS stores the amount of usable lower memory 
    ; in a word located at 0:413h in memory. We going to erase this value because
    ; we have booted dos before loading the bootsector, and dos is fat (and ugly).

    ; fake free memory  
    ;push ds
    ;push   0
    ;pop        ds
    ;mov        ax, TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
    ;mov    word ptr ds:[413h], ax  ;ax = memory in K
    ;pop ds
    ;lea si, memory_patched_msg
    ;call print

    ;mov ax, cs
    mov ax, 0
    mov es, ax

    ; read first sector to es:7c00h (== cs:7c00)
    mov  dl, 80h
    mov  cl, 1
    mov  al, 1
    mov  bx, 7c00h ;load sector to es:bx
    call read_sectors

    lea si, mbr_loaded_msg
    call print

    lea si, jmp_to_mbr_msg
    call print

    ;Set BIOS default values in environment
    cli
    mov dl, 80h ;(drive C)
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0ffffh
    sti

    push es
    push 7c00h
    retf            ;Jump to MBR code at 0:7c00h


    ; Print string
print:
    xor bx, bx
    mov ah, 0eh
    cld

@@: lodsb
    test al, al
    jz print_end

    int 10h
    jmp @B

print_end:
    ret

    ; Read sectors of the first cylinder
read_sectors:
    mov ch, 0           ; Cylinder
    mov dh, 0           ; Head
                        ; DL = drive number passed from BIOS
    mov ah, 2
    int 13h
    jnc read_ok

    lea si, disk_error_msg
    call print
read_ok:
    ret

memory_patched_msg      db 'Memory patched', 13, 10, 7, 0
mbr_loaded_msg          db 'MBR loaded', 13, 10, 7, 0
jmp_to_mbr_msg          db 'Jumping to MBR code', 13, 10, 7, 0
disk_error_msg          db 'Disk error', 13, 10, 7, 0

_TEXT ENDS
END start
EN

回答 2

Stack Overflow用户

发布于 2010-11-01 07:14:47

好吧,我的DOS知识非常生疏,我还没有时间来测试/验证我的答案,但我猜你的问题如下:

当启动DOS或任何其它OS时,它们将改变中断表。DOS将改变中断表,这样例如中断20就可以用来向DOS“内核”发送命令。它们通过保存原始中断处理程序,用自己的处理程序替换它,然后在不知道如何处理中断的情况下链接到原始中断处理程序,作为默认的回退。通过这种方式,他们在已经存在的bios功能上“添加”了新的功能,并且在DOS下运行的每个程序都可以通过设置一些寄存器然后调用中断来使用系统调用。

然而,当你启动一个新的操作系统时,这个新的操作系统将假定a)所有的中断都由bios处理,以及b)所有的内存都是空闲的/未使用的,除非bios报告正在使用。

因此,新操作系统将覆盖旧操作系统当前使用的内存,然后它将在某个时刻调用其中一个中断,并在无效内存中执行某些操作,然后您的计算机将崩溃。

因此,将您的中断表重置为原始的bios版本,您应该会很好…

票数 2
EN

Stack Overflow用户

发布于 2010-04-15 02:30:06

我不认为这是一个引导加载程序,它是加载引导扇区并尝试执行它的.com文件。所以它是在DOS初始化后运行的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2639234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档