Случайные символы отображаются на реальном оборудовании, но не на симуляторе - PullRequest
0 голосов
/ 11 октября 2018

Я сейчас пишу свой собственный загрузчик.Я был в состоянии успешно загрузить его на QEMU и VirturalBox.У меня, однако, возникают проблемы на реальном оборудовании.

Вот как это должно выглядеть (это на qemu):

enter image description here

Вот как это выглядит на реальном оборудовании: enter image description here

Может кто-нибудь, пожалуйста, дайте мне знать, что здесь происходит и что я могу сделать, чтобы решить эту проблему.

Вот код printf:

printf:
  pusha
  mov ah, 0x0e    ; Teletype output function
  str_loop:
    mov al, [si]  ; Load a character byte to al
    cmp al, 0
    jne print_char  ; if al != 0, jmp to print_char
    popa
    ret

  print_char:
    int 0x10    ; 0x10 interrupt
    inc si    ; add 1 to si
    jmp str_loop

printh:

printh:
push cx
push di
push bx

mov si, HEX_PATTERN   ; Load HEX_PATTERN memory location to si
mov cl, 12
mov di, 0

.hexLoop:
  mov bx, dx      ; copy dx to bx to preserve original hex value
  shr bx, cl      ; Shift value in bx 12 bits (3 bytes) right
  and bx, 0x000F  ; mask first 3 digits
  mov bx, [bx + HEX_TABLE]  ; load ascii character from HEX_TABLE into bx
  mov [HEX_PATTERN + di], bl  ; insert byte bl into correct spot in HEX_PATTERN
  sub cl, 4       ; change bits shifted in next iteration
  inc di          ; add 1 to insertion location in HEX_PATTERN

  cmp di, 4       ; since HEX_PATTERN.length = 4:
  je .exit        ; if (di == 4) {exit the loop}

jmp .hexLoop

.exit:
call printf     ; print HEX_PETTERN which is now populated

pop bx
pop di
pop cx
ret

HEX_PATTERN db '****h', 0Ah, 0Dh, 0
HEX_TABLE db "0123456789ABCDEF"

read_disk:

;in=============================
;AL - sectors to read count
;CL - sector to read into memory
;DI - location to load
;out===========================
;CF - error

read_disk:
  pusha
  mov ah, 02h            ;We want to read a device
  mov dl, 80h            ;Spcificly a hard disk. Note: Floppy/SSDs are 00h
  mov ch, 0              ;Start at clyender 1
  mov dh, 0              ;Start at head 1
                         ;Address access pointer is where the memory is stored
                         ;This is at es:bx
  push bx
  mov bx, 0              ;Set bx to zero
  mov es, bx             ;Set segment to zero
  pop bx
  mov bx, di   ;Set offset to the address after our bootloader

  int 13h                ;Read from disk

  popa
  ret

И, наконец, основной код:

org 0x7c00            ; add to offsets
bits 16

section .text
  global main



main:
cli          ;Disable interupts
jmp 0x0000:FIRST_STEP ;Make sure we load the correct address
%include "includes/first_step.s"

mov si, BOOTLOADER_STARTED
call printf

push ax
xor ax, ax
mov dl, 80h
int 13h

mov si, DISK_RESET_MSG
call printf

call testA20
mov dx, ax
call printh

call enableA20

call testA20
mov dx, ax
call printh



mov al, 1
mov cl, 2
mov di, [SECTOR_TWO_MEMORY_LOCATION]
call read_disk
jc disk_read_error

jmp [SECTOR_TWO_MEMORY_LOCATION]

hlt

disk_read_error:
  mov si, DISK_ERROR_MSG
  call printf
  hlt

%include "includes/bootlibrary.s"


SECTOR_TWO_MEMORY_LOCATION dw 0x7C00 + 512
BOOTLOADER_STARTED db "DKBootLoader has started", 0Ah, 0Dh, 0
DISK_RESET_MSG db "Reset disk", 0Ah, 0Dh, 0
DISK_ERROR_MSG db "Error reading disk. DKOS cannot boot", 0


times 510-($-$$) db 0 ; make sure file is 510 bytes in size
dw 0xaa55             ; write boot signiture



mov si, DISK_SUCSESSFULLY_READ
call printf

mov si, CHECKING_LONG_MODE
call printf

call check_long_mode
push ax
test ax, 0
pop dx
call printh
je long_mode_enabled

long_mode_disabled:
  mov si, LONG_MODE_DISABLED_MSG
  call printf
  hlt

long_mode_enabled:
mov si, LONG_MODE_ENABLED_MSG
call printf
hlt

%include "check_long_mode.s"

DISK_SUCSESSFULLY_READ db "Disk sucsessfully read. In second sector", 0Ah, 0Dh, 0
CHECKING_LONG_MODE db "Checking long mode", 0Ah, 0Dh, 0

LONG_MODE_ENABLED_MSG db "Long mode is enabled", 0Ah, 0Dh, 0
LONG_MODE_DISABLED_MSG db "Long mode is not avaliable", 0Ah, 0Dh, 0

times (512*2)-($-$$) db 0 ; make sure file is 510 bytes in size

Если вам нужно больше функций, дайте мне знать.Здесь я думаю, что это может быть неудачно.

Наконец, вот шестнадцатеричный дамп:

00000000: faea 067c 0000 31c0 8ed0 8ed8 8ec0 8ee0  ...|..1.........
00000010: 8ee8 bc00 7cfc be7f 7de8 3900 5031 c0b2  ....|...}.9.P1..
00000020: 80cd 13be 9a7d e82c 00e8 9300 89c2 e834  .....}.,.......4
00000030: 00e8 c200 e888 0089 c2e8 2900 b001 b102  ..........).....
00000040: 8b3e 7d7d e862 0072 05ff 267d 7df4 bea7  .>}}.b.r..&}}...
00000050: 7de8 0100 f460 b40e 8a04 3c00 7502 61c3  }....`....<.u.a.
00000060: cd10 46eb f351 5753 be91 7cb1 0cbf 0000  ..F..QWS..|.....
00000070: 89d3 d3eb 83e3 0f8b 9f99 7c88 9d91 7c80  ..........|...|.
00000080: e904 4783 ff04 7402 ebe6 e8c8 ff5b 5f59  ..G...t......[_Y
00000090: c32a 2a2a 2a68 0a0d 0030 3132 3334 3536  .****h...0123456
000000a0: 3738 3941 4243 4445 4660 b402 b280 b500  789ABCDEF`......
000000b0: b600 53bb 0000 8ec3 5b89 fbcd 1361 c360  ..S.....[....a.`
000000c0: a1fe 7d53 bbff ff8e c35b bb0e 7e26 8b17  ..}S.....[..~&..
000000d0: 39d0 7405 61b8 0100 c3a1 ff7d 53bb ffff  9.t.a......}S...
000000e0: 8ec3 5bbb 0f7e 268b 1739 d074 0561 b801  ..[..~&..9.t.a..
000000f0: 00c3 6131 c0c3 60b8 0124 cd15 e8c0 ff83  ..a1..`..$......
00000100: f801 744c fbe8 5000 b0ad e664 e849 00b0  ..tL..P....d.I..
00000110: d0e6 64e8 4900 e460 50e8 3c00 b0d1 e664  ..d.I..`P.<....d
00000120: e835 0058 0c02 e660 e82d 00b0 aee6 64e8  .5.X...`.-....d.
00000130: 2600 fbe8 89ff 83f8 0174 15e4 920c 02e6  &........t......
00000140: 92e8 7bff 3c01 7408 be66 7de8 07ff ebfe  ..{.<.t..f}.....
00000150: be6f 7de8 fffe 61c3 e464 a802 75fa c3e4  .o}...a..d..u...
00000160: 64a8 0174 fac3 4e6f 2041 3230 0a0d 0041  d..t..No A20...A
00000170: 3230 2045 6e61 626c 6564 0a0d 0000 7e44  20 Enabled....~D
00000180: 4b42 6f6f 744c 6f61 6465 7220 6861 7320  KBootLoader has 
00000190: 7374 6172 7465 640a 0d00 5265 7365 7420  started...Reset 
000001a0: 6469 736b 0a0d 0045 7272 6f72 2072 6561  disk...Error rea
000001b0: 6469 6e67 2064 6973 6b2e 2044 4b4f 5320  ding disk. DKOS 
000001c0: 6361 6e6e 6f74 2062 6f6f 7400 0000 0000  cannot boot.....
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.
00000200: be6c 7ee8 4ffe be97 7ee8 49fe e818 0050  .l~.O...~.I....P
00000210: a900 005a e84e fe74 07be c37e e836 fef4  ...Z.N.t...~.6..
00000220: beac 7ee8 2ffe f460 669c 6658 6689 c166  ..~./..`f.fXf..f
00000230: 3500 0020 0066 5066 9d66 9c66 5866 31c8  5.. .fPf.f.fXf1.
00000240: 7425 66b8 0000 0080 0fa2 663d 0100 0080  t%f.......f=....
00000250: 7215 66b8 0100 0080 0fa2 66f7 c200 0000  r.f.......f.....
00000260: 2074 0461 31c0 c361 b801 00c3 4469 736b   t.a1..a....Disk
00000270: 2073 7563 7365 7373 6675 6c6c 7920 7265   sucsessfully re
00000280: 6164 2e20 496e 2073 6563 6f6e 6420 7365  ad. In second se
00000290: 6374 6f72 0a0d 0043 6865 636b 696e 6720  ctor...Checking 
000002a0: 6c6f 6e67 206d 6f64 650a 0d00 4c6f 6e67  long mode...Long
000002b0: 206d 6f64 6520 6973 2065 6e61 626c 6564   mode is enabled
000002c0: 0a0d 004c 6f6e 6720 6d6f 6465 2069 7320  ...Long mode is 
000002d0: 6e6f 7420 6176 616c 6961 626c 650a 0d00  not avaliable...
000002e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000002f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000300: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000310: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000320: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000330: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000340: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000350: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000360: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000370: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000380: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000390: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000003f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

В чем причина этого и что я могу сделать, чтобы это исправить?Я также пытался читать разные диски.
Это тоже не работает.

Кроме строк, которые не отображаются правильно, второй сектор тоже не загружается.

Iтакже запустил qemu с файлом /dev/disk2, который является моим жестким диском.Там нет проблем.Только на физическом компьютере.



Редактировать :

По запросу, first_steps.s:

FIRST_STEP:
             ;Zero out all general purpose registers
xor ax, ax
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov sp, main ;Set our stack pointer to the address of our 'main'lable
cld          ;Clear the direction flag - controls order we read strings

1 Ответ

0 голосов
/ 13 октября 2018

Во-первых, я бы упростил код, реализовав только необходимые функции.Не то, чтобы использование ORG было неправильным, но эта преамбула гарантирует, что он будет работать даже с некоторыми причудливыми BIOS.Я думаю, можно с уверенностью предположить, что вы не используете компоновщик, поэтому разделы бесполезны в плоском двоичном файле.

Преамбула

    BOOT_SEG    equ 0x7c00
         TTY    equ 0x0E
       VIDEO    equ 0x10

    jmp     BOOT_SEG:Start      ; Guarantee that CS = 0x7c00:Start

Start:  
    mov ax, cs
    mov ds, ax
    mov es, ax          ; Initialize primary segment registers

    ; Then set stack pointer to a safe place (*98000H*) but this does make the
    ; assumption that machine has at least 1M of ram.

    cli
    mov ax, 0x9000
    mov ss, ax
    mov sp, 0x8000
    sti

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

printf:
    mov ah, TTY
 .L0:
    lodsb
    or  al, al
    jnz .J1
    ret
  .J1:
    int VIDEO
    jmp .L0

Эмуляторы являются изумительными инструментами, но на моей тестовой машине я используюактуальная версия DOS 6.2, которая чрезвычайно удобна для решения некоторых проблем.В любом случае, я думаю, что если вы реализуете Преамбулу, я вполне уверен, что она решит вашу проблему или, если не более, исключит из возможных вариантов.

...