2010-04-14 20 views
6

Für ein Projekt möchte ich den MBR auf der ersten Festplatte direkt von DOS aufrufen. Ich habe ein kleines Assemblerprogramm geschrieben, das den MBR bei 0: 7c00h in den Speicher lädt und einen weiten Sprung dazu macht. Ich habe mein Util auf eine bootfähige DOS-Diskette gelegt. Auf der Festplatte (HD0, 0x80), die ich starten möchte, befindet sich ein TrueCrypt-Bootloader. Wenn ich das Tool in diesem Setup starte, wird der TrueCrypt-Bildschirm angezeigt, aber nach Eingabe des Passworts stürzt das System ab. Wenn ich meine kleine Utility (w00t.com) auf einer normalen WinXP-Maschine starte, scheint sie sofort zu stürzen.MBR Booten von DOS

Offenbar vergesse ich einige wichtige Sachen, die das BIOS normalerweise tut, meine Vermutung ist, dass es etwas Triviales ist. Kann mir jemand mit besserer Bare-Metal DOS- und BIOS-Erfahrung helfen?

Heres mein Code:

.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 

Antwort

1

Herausgegeben - neue Antwort:

OK, scheint, wie ich zuerst die Frage falsch verstanden. Die einzigen weitere Ratschläge, die ich geben kann, ist dies:

  • überprüfen Sie, ob Sie laden entweder HIMEM.SYS und/oder EMM386.EXE (oder einen anderen Speichermanager) nicht. Die CPU muss im Real Mode sein, wenn der Bootloader ausgeführt wird.

  • Werfen Sie einen Blick auf Ralf Browns Interrupt-Liste. Wenn ich mich richtig erinnere, gibt es irgendwo technische Informationen über den Boot-Vorgang. Es könnte dir einen Hinweis geben.

  • Schauen Sie sich den Quellcode anderer Ladeprogramme an, z. loadlin. (Es ist nicht genau das gleiche wie Ihr Nutzen, sondern vielleicht einen kleinen Einblick geben, dennoch.)


Zurück Antwort:

Ist ORG 100h wirklich die Richtige Sache in einem Bootloader zu tun?

Ich dachte, das war nur relevant für DOS .com ausführbare Dateien, weil DOS die ersten 256 Bytes mit dem Program Segment Prefix (PSP) initialisiert werden. Wenn Sie einen Bootloader schreiben, gibt es kein DOS und keine PSP. Ich nehme an, das muss ORG 0 sein.

+0

Es ist eine COM-Datei in der Tat, so dass whys ist es bei 100h ORGed ist. Genau wie jede andere .com-Datei. Es lädt den MBR in mem und springt auf is. Wie Sie in meiner ersten Frage lesen können, erledigt es den Job: Der TrueCrypt Bootloader wird gestartet und zeigt den richtigen Bildschirm an. So funktioniert das Laden und Springen. Erst danach friert der Computer ein. Etwas muss falsch sein, vielleicht ist die Umgebung nicht richtig eingestellt? – Rogier

+0

Wenn dieser TrueCrypt-Bootloader auf Ihrer Festplatte _expects_ eine normale '.com'-Datei erwartet, sollte das' ORG 100h' kein Problem darstellen. Ansonsten denke ich, dass es ein Fehler ist. - Zweitens ist es nicht verwunderlich, dass Ihr Programm abstürzt, wenn es unter Windows XP ausgeführt wird. Wenn der Computer zum ersten Mal gestartet wird, befindet sich die CPU im Real-Modus (8086-Emulation), und Boot-Loader erwarten dies. Sobald Windows XP gestartet ist, wird die CPU niemals wieder in den Real-Modus wechseln. DOS-Programme werden möglicherweise im sogenannten Virtual 8086-Modus ausgeführt (wenn ich mich an den Namen richtig erinnere), und Bootloader funktionieren in diesem CPU-Modus nicht. – stakx

+0

Nein, sogar das Laden eines Bootloaders auf Adresse 0: 7c00 ist in Windows (XP) mit diesen Utils nicht möglich. Sie können nicht direkt von Windows auf die Festplatte zugreifen und Sie können nicht einfach im Mem herumlaufen. Aber bitte lesen Sie in meiner Frage, dass ich das Tool von Floppy (Bild) ausführen, d. H. Es läuft in DOS, 16bit Real-Modus. Darüber hinaus ist die Arbeit teilweise schon erledigt; Der TC Bootloader GETS wurde gestartet und zeigt den Bildschirm "Willkommen bei TC, bitte pass password" an. Erst danach knackt es. Ergo, in der Umgebung, die das BIOS normalerweise einrichtet, muss etwas falsch sein. – Rogier

0

Ich glaube nicht, dass dies ein Bootloader ist, es ist .com-Datei, die den Boot-Sektor lädt und versucht, es auszuführen. So läuft es nach DOS wurde initialisiert.

1

Ok mein DOS Wissen ist sehr rostig und ich habe nicht die Zeit zu testen/zu validieren meine Antwort hat, aber ich denke, das Problem wie folgt:

Wenn DOS Boote oder andere OS, werden sie ändern die Unterbrechungstabelle. DOS wird die Interrupt-Tabelle so ändern, dass beispielsweise Interrupt 20 verwendet werden kann, um Befehle an den DOS- "Kernel" zu senden. Sie tun dies, indem sie den ursprünglichen Interrupt-Handler speichern, ihn durch ihren eigenen Handler ersetzen und anschließend als Standard-Fallback den ursprünglichen Interrupt-Handler verketten, wenn sie nicht wissen, wie sie mit dem Interrupt umgehen sollen.Auf diese Weise fügen sie der bereits vorhandenen Bios-Funktionalität neue Funktionen hinzu, und jedes Programm, das unter DOS läuft, kann den Systemaufruf verwenden, indem es nur einige Register setzt und dann den Interrupt aufruft.

Wenn Sie jedoch ein neues Betriebssystem starten, geht dieses neue Betriebssystem davon aus, dass a) alle Interrupts vom BIOS verarbeitet werden und b) der gesamte Speicher frei/unbenutzt ist, es sei denn, es wird von diesem BIOS verwendet.

Also überschreibt der neue os den Speicher, der gerade von Ihrem alten Betriebssystem verwendet wird und dann wird er irgendwann einen der Interrupts aufrufen und etwas in ungültigem Speicher ausführen, und Ihr Computer wird abstürzen.

So setzen Sie Ihre Interrupt-Tabelle auf die ursprüngliche BIOS-Version und Sie sollten in Ordnung sein ...

+0

Hey, das hört sich plausibel an! Vielen Dank. – Rogier