Il codice presuppone che DS sia impostato su 0. Non è possibile presumere che. La prima parte del codice deve impostare esplicitamente DS su 0 se si utilizza org 0x7c00
.
Si dovrebbe seriamente considerare di definire il proprio stack impostando SS: SP. Non sai dove si trova l'esistente o se è abbastanza grande da gestire quello che intendi fare.
Appena prima che venga richiamato il bootloader, il BIOS imposta lo DL con il numero del dispositivo di avvio. Non impostare DL a 0 nel codice quando si effettuano richieste di unità dall'unità di avvio. Dovresti utilizzare il valore che esisteva in DL quando è stato chiamato il tuo bootloader.
si dovrebbe usare il CLD istruzioni per cancellare il flag di direzione dal momento che si sta utilizzando il LODSB istruzioni aspettandosi di essere in movimento in avanti in memoria. Non è garantito che il flag di direzione sia impostato correttamente, pertanto è necessario impostarlo esplicitamente nella direzione desiderata con CLD (inoltro) o STD (indietro).
Ho più informazioni sui problemi di cui sopra nella mia risposta StackOverflow con General Bootloader Tips.
Poiché non si utilizza uno BPB, si consiglia vivamente di rimuovere lo jmp start
come prima istruzione del proprio bootloader. Spostare invece i dati dopo il codice ma prima della firma del settore di avvio (0xAA55
). La ragione di ciò è che alcuni BIOS tenteranno di trovare un BPB basato su un'istruzione JMP che appare come prima istruzione del bootloader e, se trovato, sovrascrive parti del bootloader in memoria causando un comportamento potenzialmente indefinito.
vostro bootloader usa questa istruzione per iniziare la seconda fase caricato dal secondo settore:
jmp 0x0:0x1000
Il problema è che quando si legge il settore creazione ES: BX in questo modo:
read_sector:
mov ax, 0x0
mov es, ax
xor bx, bx
Questo imposta ES: BX a 0x0000: 0x0000 che chiaramente non è dove il vostro JMP si aspetta che il codice sia. È necessario impostare ES: BX nella posizione di memoria che si desidera INT 13/AH=02h per leggere i settori del disco in.
INT 13h/AH = 02h richiede che il numero di Cilindro/Testina/Settore sia impostato correttamente. I settori iniziano la numerazione a 1, ma Cilindri e teste sono a base zero. Il secondo settore del disco è a cilindro 0, testina 0, settore 2. Il codice imposta Cilindro a 1 invece di 0. Questo codice è sbagliato in quanto si dovrebbe davvero essere impostando a 0:
mov ch, 01
Nella tua nella seconda fase è stato creato print
come funzione poiché termina con un'istruzione RET
. jmp print
deve essere modificato in call print
.
Con tutti i cambiamenti sopra raccomandate, tra cui quelli di miei consigli generali bootloader il codice potrebbe essere modificato per essere:
boot.asm
[bits 16]
[org 0x7c00]
; Use the boot drive number passed to us by BIOS in register DL
start:
xor ax,ax ; We want a segment of 0 for DS for this question
mov ds,ax ; Set AX to appropriate segment value for your situation
mov es,ax ; In this case we'll default to ES=DS
mov bx,0x8000 ; Stack segment can be any usable memory
mov ss,bx ; This places it with the top of the stack @ 0x80000.
mov sp,ax ; Set SP=0 so the bottom of stack will be @ 0x8FFFF
cld ; Set the direction flag to be positive direction
mov si, wolf_wel_msg
call wolf_print
mov si, wolf_kernel_load
call wolf_print
pushf
stc
mov ah,00
int 13h
read_sector:
mov ax, 0x0
mov es, ax ; ES = 0
mov bx, 0x1000 ; BX = 0x1000. ES:BX=0x0:0x1000
; ES:BX = starting address to read sector(s) into
mov ah, 02 ; Int 13h/AH=2 = Read Sectors From Drive
mov al, 01 ; Sectors to read = 1
mov ch, 00 ; CH=Cylinder. Second sector of disk
; is at Cylinder 0 not 1
mov cl, 02 ; Sector to read = 2
mov dh, 00 ; Head to read = 0
; DL hasn't been destroyed by our bootloader code and still
; contains boot drive # passed to our bootloader by the BIOS
int 13h
jc wolf_error
popf
jmp 0x0:0x1000
cli
hlt
wolf_error:
mov si, wolf_error_msg
call wolf_print
mov si, wolf_error_msg1
call wolf_print
mov ah,00
int 16h
xor ax,ax
int 19h
wolf_print:
lodsb
or al,al
jz exit
mov ah,0x0e
int 10h
jmp wolf_print
exit:
ret
; Moved the data before the boot signature but after the code
wolf_wel_msg db 'Welcome to Bootloader!!!',0x0D,0x0A,0
wolf_kernel_load db 'Loading kernel....',0x0D,0x0A,0
wolf_error_msg db 'Kernel.bin not found!',0x0D,0x0A,0
wolf_error_msg1 db 'Press any key to restart..',0
times 510-($-$$) db 0
dw 0xAA55
hello.asm
[org 0x1000]
jmp start
data:
msg db 'Hello',0
start:
mov si, msg
call print ; print is a function, use CALL instead of JMP
cli
hlt
print:
lodsb
or al, al
jz exit
mov ah,0x0e
int 10h
jmp print
exit:
ret
Poiché sembra che si stia utilizzando Windows in base alle informazioni fornite nel comando DD, è possibile che si stia verificando un altro problema. Non so quale DD si usi ma of=\\.\d:
non scrive all'inizio del disco (unità USB), scriverà sulla partizione in cui D: risiede, non l'inizio del disco stesso.
Si consiglia di utilizzare l'ultimo DD da Chrysocome. Ad oggi l'ultimo è 0.6beta3. Raccomando questa versione perché consente di accedere correttamente al disco (o chiavetta USB) rispetto all'inizio del disco, non in relazione all'inizio di una particolare partizione. Ciò potrebbe causare seri problemi nel tentativo di memorizzare correttamente il 1 ° e il 2 ° settore. Con l'ultima versione userei questi comandi con privilegi di amministratore scrivere sul drive USB:
dd if=f:\boot.bin od=d: bs=512 count=1
dd if=f:\hello.bin od=d: bs=512 seek=1 count=1
Questo presuppone che il USB unità è sull'unità D: come suggerito nella sua interrogazione. ATTENZIONE: il mancato utilizzo dell'unità corretta potrebbe causare la perdita e la corruzione di dati su un altro dispositivo !!
Se questi comandi funzionano correttamente l'output dovrebbe essere simile:
dd if=boot.bin od=d: bs=512 count=1
rawwrite dd for windows version 0.6beta3.
Written by John Newbigin <[email protected]>
This program is covered by terms of the GPL Version 2.
Device d: is a link to \\?\Device\HarddiskVolume5 \\?\Device\HarddiskVolume5 is a partition on \Device\Harddisk1
512 100%
1+0 records in
1+0 records out
dd if=hello.bin od=d: bs=512 seek=1 count=1
rawwrite dd for windows version 0.6beta3.
Written by John Newbigin <[email protected]>
This program is covered by terms of the GPL Version 2.
Device d: is a link to \\?\Device\HarddiskVolume5 \\?\Device\HarddiskVolume5 is a partition on \Device\Harddisk1
28 5%
0+1 records in
0+1 records out
Una volta che avete rilasciato questi comandi, Windows può rilevare automaticamente che l'unità non è più formattato correttamente. Non consentire a Windows di formattare l'unità. Se gli permetti di formattare il disco, lo ripartirà e lo formatterà. In tal modo distruggerà il settore di avvio che hai scritto. Quando richiesto, è sufficiente annullare la finestra di dialogo in formato .
Ricordarsi di smontare/espellere correttamente l'unità USB prima di rimuoverla dal sistema. La mancata corretta installazione potrebbe far sì che i dati non vengano scritti correttamente/completamente nell'unità.
Se si desidera creare un'immagine del disco per Bochs, QEMU, DOSBox ecc si potrebbe creare un floppy 720k con questi comandi al prompt dei comandi:
dd if=/dev/zero of=disk.img bs=1024 count=720
dd if=f:\boot.bin of=disk.img bs=512 count=1 conv=notrunc
dd if=f:\hello.bin of=disk.img bs=512 seek=1 count=1 conv=notrunc
L'immagine del file disk.img
dovrebbe essere utilizzabile da Bochs, QEMU , DOSbox, ecc. O scritti su un dischetto da 720k per l'uso su un computer reale.
/dev/zero
si presenta come un tipico dispositivo Unix/Linux. Il comando DD per Windows che ho suggerito di utilizzare comprende /dev/zero
come un dispositivo di input speciale che genera solo zeri. Windows non ha il dispositivo /dev/zero
, ma DD lo vede come un dispositivo interno speciale e lo simula.
Quando viene eseguito con Bochs 2.6.8 su MS Windows questo è quello che ho visto:
Sul mio Lenovo L520 Laptop (non-EFI BIOS) con un'USB Stick 16GB questo è quello che ho visto:
Che cosa hai già provato? Cosa esattamente "non funziona"? Hai qualche risultato? – Yexo
No, ricevo l'output dicendo "kernel.bin non trovato". Significa che carry è impostato (non riuscito). –
"ciao.bin" non caricato dal secondo settore. –