そのため、ここ数週間、アセンブリ (x86/x86_64) でブートローダーとカーネルを作成する方法を検討してきました。より複雑なソリューションを試してみましたが、自分で作成する前に、Sinnedという名前のユーザーがここに投稿したコードを試してみることにしました。私のブートローダーコードは次のとおりです。
[BITS 16]
[ORG 0x7C00]
MOV DL, 0x0 ;drive 0 = floppy 1
MOV DH, 0x0 ;head (0=base)
MOV CH, 0x0 ;track/cylinder
MOV CL, 0x02 ;sector (1=bootloader, apparently sectors starts counting at 1 instead of 0)
MOV BX, 0x1000 ;place in RAM for kernel - I suppose randomly chosen on examples
MOV ES, BX ;place BX in pointer ES
MOV BX, 0x0 ;back to zero - also has something to do with RAM position
ReadFloppy:
MOV AH, 0x02
MOV AL, 0x01
INT 0x13
JC ReadFloppy ;if it went wrong, try again
;pointers to RAM position (0x1000)
MOV AX, 0x1000
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
JMP 0x1000:0x0
;assuming we get never back here again, so no further coding needed (kernel handles everything now)
TIMES 510 - ($ - $$) db 0 ;fill resting bytes with zero
DW 0xAA55 ;end of bootloader (2 bytes)
私のカーネルファイルは次のとおりです。
;set print-registers
MOV AH, 0x0E ;function nr
MOV BH, 0x00 ;page
MOV BL, 0x07 ;color
MOV SI, msg ;move msg to SI-pointer
CALL PrintString ;call function to print SI (msg)
JMP $ ;hang
PrintString:
.next_char:
MOV AL, [SI] ;current character
OR AL, AL
JZ .print_done ;if current char is zero, go to end
INT 0x10 ;print character
INC SI ;increase pointer to msg (next character)
JMP .next_char
.exit_char
RET
msg db 'Hello world from the kernel!', 13, 10, 0
TIMES 512 - ($ - $$) db 0 ;fill the rest
すべてをうまく組み立てることができ、フロッピーコントローラーに接続すると、VirtualBox内で作成された単一のバイナリが起動します。これにより、自分のローダーとカーネルで作業する自信が持てますが、ベアメタルで起動することに満足したいと思っています。
USB ドライブを使用してイメージを起動しようとしましたが、うまくいきませんでした。USB スティックを正しくイメージングしていることは確かです。ここで本当に明白な何かが欠けていると感じ始めています。USBから生のバイナリを実際に読み取ろうとしている「フロッピー」から読み取るために13hを使用することに関係があると思われます。これは事実ですか?もしそうなら、フロッピーの代わりに特定されていないディスクから読み取るようにブートローダーを書き直すにはどうすればよいですか?