2010-04-14 5 views
6

Pour un projet, je voudrais appeler le MBR sur le premier disque dur directement à partir de DOS. J'ai écrit un petit programme assembleur qui charge le MBR en mémoire à 0: 7c00h et fait un saut lointain. J'ai mis mon util sur une disquette bootable (DOS). Le disque (HD0, 0x80) que j'essaie de démarrer contient un chargeur de démarrage TrueCrypt. Lorsque je lance l'outil dans cette configuration, il affiche l'écran TrueCrypt, mais après avoir entré le mot de passe, il plante le système. Quand je lance ma petite utlility (w00t.com) sur une machine WinXP normale, elle semble se briser immédiatement.Démarrage MBR à partir du DOS

Apparemment, j'oublie certaines choses cruciales que le BIOS fait normalement, je suppose que c'est quelque chose de trivial. Est-ce que quelqu'un avec une meilleure expérience en DOS et BIOS peut m'aider?

Heres mon 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 

Répondre

1

Edité - nouvelle réponse:

OK, semble que j'ai mal compris votre question. Le seul autre conseil que je peux donner est la suivante:

  • Vérifiez que vous ne chargez soit HIMEM.SYS et/ou EMM386.EXE (ni aucun autre gestionnaire de mémoire). Le CPU doit être en mode réel lorsque le bootloader est exécuté.

  • Jetez un oeil à la liste d'interruptions de Ralf Brown. Si je me souviens bien, il y a quelque part des informations techniques sur le processus de démarrage. Cela pourrait vous donner un indice. Regardez le code source des autres utilitaires du chargeur, par ex. loadlin. (Il ne fait pas exactement la même chose que votre utilitaire, mais peut vous donner une idée, quand même.)


Réponse précédente:

Est-ce vraiment la ORG 100h bonne chose à faire dans un chargeur de démarrage?

Je pensais que c'était juste pertinent pour DOS .com exécutables, parce que DOS va initialiser les 256 premiers octets avec le préfixe de segment de programme (PSP). Si vous écrivez un chargeur de démarrage, il n'y a pas de DOS, et pas de PSP. Je suppose que cela doit être ORG 0.

+0

Il est un fichier COM en effet, si c'est pourquoi il est ORGed à 100h. Tout comme n'importe quel autre fichier .com. Il charge le MBR à mem et saute à est. Comme vous pouvez le lire dans ma question initiale, il fait le travail: le chargeur de démarrage TrueCrypt démarre et affiche le bon écran. Donc, le chargement et le saut fonctionne. Seulement après cela, l'ordinateur se fige. Quelque chose doit être faux, peut-être que l'environnement n'est pas réglé correctement? – Rogier

+0

Si le chargeur de démarrage TrueCrypt sur votre disque _expecte_ un fichier '.com' normal, alors le' ORG 100h' ne devrait pas poser de problème. Sinon, je pense que c'est une erreur. - Deuxièmement, il n'est pas surprenant que votre programme se bloque lorsqu'il est exécuté sous Windows XP. Lorsque l'ordinateur démarre pour la première fois, le processeur est en mode réel (émulation 8086) et les chargeurs de démarrage l'attendent. Une fois que Windows XP a démarré, le processeur ne reviendra jamais en mode réel. Les programmes DOS peuvent être exécutés dans ce qu'on appelle le mode Virtual 8086 (si je me souviens bien du nom), et les bootloaders ne fonctionneront pas dans ce mode CPU. – stakx

+0

Non, même charger un chargeur de démarrage à l'adresse 0: 7c00 n'est pas possible sous Windows (XP) avec cet utilitaire. Vous ne pouvez pas accéder au disque directement à partir de Windows et vous ne pouvez pas vous contenter de vous déplacer dans le mem. Mais s'il vous plaît lisez dans ma question que je cours l'outil à partir de disquette (image), c'est-à-dire qu'il s'exécute en DOS, mode réel 16 bits. En outre est en fait le travail en partie déjà; le GETS Bootloader TC a démarré et affiche l'écran "Bienvenue à TC, s'il vous plaît entrer mot de passe". Seulement après ça ça croute. Ergo, il doit y avoir quelque chose de mal dans l'environnement que le BIOS met normalement en place. – Rogier

0

Je ne pense pas que ce soit un chargeur de démarrage, c'est le fichier .com qui charge le secteur de démarrage et essaie de l'exécuter. Donc, il fonctionne après que DOS a été initialisé.

1

Ok ma connaissance DOS est très rouillée et je n'ai pas eu le temps de tester/valider ma réponse, mais je suppose que votre problème est la suivante:

Lorsque DOS démarrage ou tout autre système d'exploitation, ils altéreront la table d'interruption. DOS va changer la table d'interruption de sorte que - par exemple - l'interruption 20 peut être utilisée pour envoyer des commandes au "noyau" DOS. Ils le font en sauvegardant le gestionnaire d'interruption d'origine, en le remplaçant par leur propre gestionnaire et ensuite, en tant que solution de secours par défaut, en les associant au gestionnaire d'interruption d'origine s'ils ne savent pas comment gérer l'interruption.De cette façon, ils "ajoutent" de nouvelles fonctionnalités à la fonctionnalité du bios déjà existante, et chaque programme s'exécutant sous DOS peut utiliser l'appel système en définissant simplement des registres, puis en appelant l'interruption. Cependant, lorsque vous démarrez un nouveau système d'exploitation, ce nouveau système d'exploitation suppose que a) toutes les interruptions sont traitées par le BIOS et b) toute la mémoire est libre/inutilisée sauf si elle est utilisée par ce BIOS. Ainsi, le nouvel os remplacera la mémoire actuellement utilisée par votre ancien système d'exploitation, puis il appellera l'une des interruptions et exécutera quelque chose dans une mémoire invalide, et votre ordinateur tombera en panne.

Donc, réinitialiser votre table d'interruption à la version du BIOS original et vous devriez être bien ...

+0

Hey cela semble plausible! Merci. – Rogier

Questions connexes