Для проекта я хотел бы вызвать MBR на первый жесткий диск непосредственно от DOS. Я записал маленькую ассемблерную программу, которая загружает MBR в памяти в 0:7c00h далекого перехода к нему. Я поместил свой util на (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
Отредактировано - новый ответ:
Хорошо, похоже, я сначала неправильно понял ваш вопрос. Единственный дополнительный совет, который я могу дать:
Убедитесь, что вы не загружаете HIMEM.SYS
и / или EMM386.EXE
(или какой-либо другой менеджер памяти). CPU должен находиться в реальном режиме при выполнении загрузчика.
Взгляните на список прерываний Ральфа Брауна. Если я правильно помню, где-то там есть техническая информация о процессе загрузки. Это может дать вам подсказку.
Посмотрите исходный код других утилит загрузчика, например loadlin
. (Это не совсем то же самое, что и ваша утилита, но, тем не менее, может дать вам некоторое представление.)
Предыдущий ответ:
Действительно ли ORG 100h
правильно делать в загрузчик?
Я думал, что это актуально только для исполняемых файлов DOS .com
, потому что DOS инициализирует первые 256 байтов с помощью префикса сегмента программы (PSP). Если вы напишете загрузчик, DOS и PSP не будет. Я предполагаю, что это должно быть ORG 0
.
Я не думаю, что это загрузчик, это .com файл, который загружает загрузочный сектор и пытается его выполнить. Поэтому он запускается после инициализации DOS.