MBR Загрузка из DOS - PullRequest
       45

MBR Загрузка из DOS

6 голосов
/ 14 апреля 2010

Для проекта я хотел бы вызвать MBR на первом жестком диске непосредственно из DOS. Я написал небольшую программу на ассемблере, которая загружает MBR в память в 0: 7c00h и делает большой скачок к ней. Я положил свой утилиту на (DOS) загрузочную дискету. Диск (HD0, 0x80), который я пытаюсь загрузить, содержит загрузчик TrueCrypt. Когда я запускаю инструмент в этой настройке, он показывает экран TrueCrypt, но после ввода пароля происходит сбой системы. Когда я запускаю свой маленький utlility (w00t.com) на обычном компьютере с WinXP, он, похоже, сразу падает.

Очевидно, я забыл некоторые важные вещи, которые обычно делает BIOS, я думаю, что это что-то тривиальное. Может ли кто-нибудь с лучшим опытом работы с DOS и BIOS с голым металлом помочь мне?

Вот мой код:

.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

Ответы [ 3 ]

2 голосов
/ 01 ноября 2010

Хорошо, мои знания DOS очень ржавые, и у меня не было времени проверить / подтвердить свой ответ, но я думаю, что ваша проблема заключается в следующем:

При загрузке DOS или любой другой ОС они изменят таблицу прерываний. DOS изменит таблицу прерываний, так что, например, прерывание 20 можно использовать для отправки команд в «ядро» DOS. Они делают это, сохраняя оригинальный обработчик прерываний, заменяя его своим собственным обработчиком, а затем, как запасной вариант по умолчанию, связывают с исходным обработчиком прерываний, если они не знают, как обрабатывать прерывание. Таким образом они «добавляют» новые функциональные возможности к уже существующей функциональности bios, и каждая программа, работающая под DOS, может использовать системный вызов, просто установив несколько регистров и затем вызвав прерывание.

Однако, когда вы загружаете новую операционную систему, эта новая операционная система будет предполагать, что а) все прерывания обрабатываются биосом и б) вся память свободна / не используется, если только об этом не сообщит этот биос.

Таким образом, новая ОС перезапишет память, используемую в настоящее время вашей старой ОС, а затем в какой-то момент вызовет одно из прерываний и выполнит что-то в недействительной памяти, и ваш компьютер выйдет из строя.

Итак, верните таблицу прерываний в исходную версию BIOS, и все будет в порядке ...

2 голосов
/ 14 апреля 2010

Отредактировано - новый ответ:

ОК, похоже, я впервые неправильно понял ваш вопрос. Единственный дополнительный совет, который я могу дать, это:

  • Убедитесь, что вы не загружаете HIMEM.SYS и / или EMM386.EXE (или любой другой менеджер памяти). Процессор должен находиться в реальном режиме при запуске загрузчика.

  • Посмотрите на список прерываний Ральфа Брауна. Если я правильно помню, там где-то есть техническая информация о процессе загрузки. Это может дать вам подсказку.

  • Посмотрите на исходный код других утилит загрузчика, например, loadlin. (Это не то же самое, что ваша утилита, но, тем не менее, может дать вам некоторое представление.)


Предыдущий ответ:

Является ли ORG 100h действительно правильной вещью в загрузчике?

Я думал, что это просто актуально для исполняемых файлов DOS .com, потому что DOS инициализирует первые 256 байтов с префиксом сегмента программы (PSP). Если вы пишете загрузчик, нет DOS, и нет такой вещи, как PSP. Я предполагаю, что это должно быть ORG 0.

0 голосов
/ 14 апреля 2010

Не думаю, что это загрузчик, это файл .com, который загружает загрузочный сектор и пытается его выполнить. Таким образом, он запускается после инициализации DOS.

...