2010-04-14 13 views
6

Per un progetto, vorrei richiamare l'MBR sul primo disco rigido direttamente da DOS. Ho scritto un piccolo programma assembler che carica l'MBR in memoria a 0: 7c00h e fa un salto molto lontano. Ho messo il mio util su un dischetto di avvio (DOS). Il disco (HD0, 0x80) che sto cercando di avviare ha un caricatore di avvio TrueCrypt su di esso. Quando eseguo lo strumento in questa configurazione, viene visualizzata la schermata TrueCrypt, ma dopo aver inserito la password si blocca il sistema. Quando eseguo la mia piccola utilità (w00t.com) su una normale macchina WinXP, mi sembra che si blocca immediatamente.MBR Avvio da DOS

Apparentemente sto dimenticando alcune cose cruciali che il BIOS normalmente fa, suppongo che sia qualcosa di banale. Qualcuno con una migliore esperienza DOS e BIOS bare metal mi può aiutare?

Heres il mio codice:

.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 

risposta

1

Edited - nuova risposta:

OK, sembra che in primo luogo ho frainteso la tua domanda. L'unica ulteriore consiglio che posso dare è questo:

  • Verificare che non si carica sia HIMEM.SYS e/o EMM386.EXE (né alcun altro gestore della memoria). La CPU deve essere in modalità Real quando viene eseguito il bootloader.

  • Dai un'occhiata all'elenco degli interrupt di Ralf Brown. Se ricordo bene, ci sono alcune informazioni tecniche da qualche parte sul processo di avvio. Potrebbe darti un suggerimento.

  • Consultare il codice sorgente di altri programmi di utilità del caricatore, ad es. loadlin. (Non fa esattamente la stessa cosa come il vostro programma di utilità, ma potrebbe dare una certa comprensione, comunque.)


risposta precedente:

È davvero il ORG 100h cosa corretta da fare in un boot loader?

Ho pensato che fosse rilevante solo per gli eseguibili DOS .com, perché DOS inizializzerà i primi 256 byte con il prefisso del segmento di programma (PSP). Se si scrive un boot loader, non esiste un DOS e non esiste una PSP. Suppongo che questo debba essere ORG 0.

+0

Si tratta di un file COM anzi, in modo che i perché è ORGed a 100h. Proprio come qualsiasi altro file .com. Carica l'MBR su mem e salta su è. Come puoi leggere nella mia domanda iniziale, in realtà fa il lavoro: il bootloader TrueCrypt viene avviato e mostra la schermata giusta. Quindi caricare e saltare funziona. Solo dopo, il computer si blocca. Qualcosa deve essere sbagliato, forse l'ambiente non è impostato correttamente? – Rogier

+0

Se quel caricatore di avvio TrueCrypt sul disco in realtà _prepassa_ un normale file '.com', quindi il' ORG 100h' non dovrebbe essere un problema. Altrimenti, penso che sia un errore. - In secondo luogo, non sorprende che il tuo programma si arresti in modo anomalo se eseguito in Windows XP. Quando il computer si avvia per la prima volta, la CPU è in modalità Real (emulazione 8086) e i caricatori di avvio si aspettano questo. Una volta avviato Windows XP, la CPU non tornerà mai in modalità Real. I programmi DOS possono essere eseguiti in quella che viene chiamata la modalità Virtual 8086 (se ricordo il nome correttamente), e i bootloader non funzioneranno in quella modalità CPU. – stakx

+0

No, anche caricare un bootloader per indirizzare 0: 7c00 non è possibile in Windows (XP) con questo utils. Non puoi accedere al disco direttamente da Windows e non puoi semplicemente andare a curiosare nel mem. Ma per favore leggete nella mia domanda che sto eseguendo lo strumento da floppy (immagine), cioè è in esecuzione in DOS, modalità reale a 16 bit. Inoltre, in realtà fa già il lavoro in parte; il TC Bootloader GETS è stato avviato e mostra la schermata "Benvenuto in TC, inserisci password". Solo dopo questo si blocca. Ergo, ci deve essere qualcosa di sbagliato nell'ambiente che il BIOS normalmente installa. – Rogier

0

Non penso che sia un boot loader, è un file .com che carica il settore di avvio e tenta di eseguirlo. Quindi viene eseguito dopo l'inizializzazione di DOS.

1

Ok la mia conoscenza DOS è molto arrugginito e non ho avuto il tempo per testare/validare la mia risposta, ma credo che il tuo problema è il seguente:

Quando l'avvio DOS o qualsiasi altro sistema operativo, che cambierà la tabella degli interrupt. DOS cambierà la tabella degli interrupt quindi, ad esempio, l'interrupt 20 può essere utilizzato per inviare comandi al "kernel" DOS. Lo fanno salvando il gestore di interrupt originale, sostituendolo dal proprio gestore e in seguito, come fallback predefinito, concatenando al gestore di interrupt originale se non sanno come gestire l'interrupt.In questo modo "aggiungono" nuove funzionalità alla funzionalità di bios già esistente e ogni programma in esecuzione su DOS può utilizzare la chiamata di sistema semplicemente impostando alcuni registri e quindi chiamando l'interrupt.

Tuttavia, quando si avvia un nuovo sistema operativo, questo nuovo sistema operativo presuppone che a) tutti gli interrupt siano gestiti dal bios e b) tutta la memoria sia libera/inutilizzata a meno che non venga riportata in uso da quel bios.

Quindi il nuovo sistema operativo sovrascriverà la memoria attualmente in uso dal vecchio sistema operativo, quindi a un certo punto chiamerà uno degli interrupt e eseguirà qualcosa nella memoria non valida e il computer si bloccherà.

Quindi, reimpostare la vostra tabella di interrupt alla versione originale del BIOS e si dovrebbe andare bene ...

+0

Hey sembra plausibile! Grazie. – Rogier