2017-01-28 26 views
1

Я пишу загрузчик в сборке и, похоже, отлично работает на qemu, bochs и virtualbox. Однако он не загружает ядро ​​на реальном оборудовании (кажется).Bootloader работает в эмуляторах, но не на реальном оборудовании

Загрузочный загрузчик начинается с записи символа в видеопамять (для отладки), затем он считывает сектор 2 с диска и переходит в ядро. Затем ядро ​​записывает некоторые символы в видеопамять.

На реальной машине я вижу символ из загрузчика на экране, и там он висит (мигает кареткой).

Я попытался установить DS, ES, SI на ноль, и я также настраиваю сегмент стека.

Я читаю сектор 2 с диска, используя функцию bios int 13 2. Я подозреваю, что он имеет какое-то отношение к номеру накопителя. Я попытался использовать номер диска, переданный загрузчику при запуске (в dl), и вручную установить его в 0x0, 0x80 и 0x81.

Одна странная вещь, которую я заметил, это то, что ярлыки, которые я использую для прыжка, волшебным образом получает правильный адрес. Используя objdump, я вижу, например: jmp 0x2, при использовании gdb и qemu: jmp 0x7c02. CS и все остальные регистры сегментов равны нулю. Использую ли я -Ttext 0x0 или -Ttext 0x7c00 при компоновке, загрузчик отлично работает на всех эмуляторах. objdump говорит jmp 0x7c02, когда я связываюсь с -Ttext 0x7c00.

EDIT, загрузчик выглядит следующим образом:

.code16 
.text 
movw $0xb800, %ax 
movw %ax, %ds 
movw $0x0741, (0x0) 

xorw %ax, %ax 
movw %ax, %ds 
movw %ax, %si 
movw %ax, %es 

movw $0x8000, %ax 
movw %ax, %ss 
movw $0, %sp 

movb $2, %ah 
movb $1, %al 
movw $0x02, %cx 
movb $0x00, %dh 

movw $0x5000, %bx 
movw %bx, %es 
movw $0x0, %bx 
int $0x13 

ljmpw $0x5000, $0x0000 

Редактировать, Второй этап:

.code16 
.text 
    movw $0xb800, %ax 
    movw %ax, %ds 
    movw $0x0742, (0x2) 

forever: 
    jmp forever 
+0

Возле прыжков будут работать, если для них используются относительные прыжки. – MikeCAT

+0

Прошу прощения, но мы не можем помочь вам с этой небольшой информацией. Можете ли вы сделать второй загрузчик с достаточным количеством кода, чтобы продемонстрировать эту проблему и показать это нам? – fuz

+0

Попробуйте решить это, разбив на более мелкие части. Если вы печатаете символ перед загрузкой сектора 2, распечатайте еще один после этой загрузки (и отличите его от ошибки, вызванной ошибкой чтения). Сравните ваш код с доступными загрузчиками с открытым исходным кодом; возможно, они делают некоторые настройки, которые вы пропустили. Вы следовали за списком прерываний Ralf Brown для правильной настройки перед вызовами? – Netch

ответ

1

Если оборудование используется эмуляция флоппи-диска для диска USB может быть возможно, что без правильный BIOS Parameter Block (BPB) в вашем MBR, который он неправильно загружает. Многие BIOS попытаются обнаружить BPB в начале загрузчика и могут даже обновить значения с надлежащей геометрией диска после загрузки загрузчика в память. Возможно, ваш загрузчик не был обнаружен в качестве надлежащего загрузочного диска, или это было, но BIOS перезаписал часть вашего кода с информацией о геометрии диска перед ее выполнением.

Следующее добавляет BPB, который выглядит как дискета 2.88MB.

.global _start 
.code16 
.text 

_start: 
    jmp  main 
    .space 3 - (.-_start) 

    /* Configuration for a 2.88MB floppy using FAT 12 */ 
    OEMname:   .ascii  "MYBOOT " 
    bytesPerSector:  .word  512 
    sectPerCluster:  .byte  1 
    reservedSectors: .word  1 
    numFAT:    .byte  2 
    numRootDirEntries: .word  240 
    numSectors:   .word  5760 
    mediaType:   .byte  0xf0 
    numFATsectors:  .word  9 
    sectorsPerTrack: .word  36 
    numHeads:   .word  2 
    numHiddenSectors: .long  0 
    numSectorsHuge:  .long  0 
    driveNum:   .byte  0 
    reserved:   .byte  0x00 
    signature:   .byte  0x29 
    volumeID:   .long  0x54428E71 
    volumeLabel:  .ascii  "NO NAME " 
    fileSysType:  .ascii  "FAT12 " 

main: 
    movw $0xb800, %ax 
    movw %ax, %ds 
    movw $0x0741, (0x0) 

    xorw %ax, %ax 
    movw %ax, %ds 
    movw %ax, %si 
    movw %ax, %es 

    movw $0x8000, %ax 
    movw %ax, %ss 
    movw $0, %sp 

    movb $2, %ah 
    movb $1, %al 
    movw $0x02, %cx 
    movb $0x00, %dh 

    movw $0x5000, %bx 
    movw %bx, %es 
    movw $0x0, %bx 
    int $0x13 

    ljmpw $0x5000, $0x0000 

.space 510-(.-_start) 
.word 0xaa55 
+1

Это сработало, спасибо! – user2725580