helloos3.s
/* helloos3.s */ .code16 jmp entry .byte 0x90 .ascii "HELLOIPL" # ブートセクタの名前 .word 512 # 1セクタのバイト数 .byte 1 # クラスタの数 .word 1 # FAT開始セクタ .byte 2 # FATの個数 .word 224 # ルートディレクトリ領域のエントリ数 .word 2880 # ドライブのセクタ数 .byte 0xF0 # メディアタイプ .word 9 # FAT領域のセクタ数 .word 18 # 1トラックのセクタ数 .word 2 # ヘッド数 .int 0 # ? .int 2880 # ドライブのセクタ数 .byte 0, 0, 0x29 # ? .int 0xFFFFFFFF # ボリュームシリアル番号 .ascii "HELLO-OS " # ディスクの名前 .ascii "FAT12 " # フォーマットの名前 .space 18 // プログラム entry: movw $0, %ax movw %ax, %ss movw $0x7C00, %sp movw %ax, %ds movw %ax, %es movw $msg, %si putloop: movb (%si), %al add $1, %si cmp $0, %al je fin # メッセージの後ろの0x00で終了する movb $0x0E, %ah # Write Character in TTY Mode movw $15, %bx # カラーコード int $0x10 # BIOS interrupt call jmp putloop fin: hlt jmp fin // メッセージ msg: .string "\n\nhello, world\n" .org 0x1FE .byte 0x55, 0xAA # 55AAでブートセクタ // ブートセクタ以降 .byte 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 .space 4600 .byte 0xF0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 .space 1469432起動時はリアルモードなので、.code16で、16bitコードを生成するように指定する。
ELFヘッダをスキップしたイメージを作るには、リンカスクリプトを使えば良いことが分かった。
NASMのORGに相当するものはGASには無いので、ORGで指定するアドレスはリンカスクリプトで設定する。
lnk.ls
OUTPUT_FORMAT("binary"); IPL_BASE = 0x7C00; SECTIONS { . = IPL_BASE; }今までは、asコマンドとddコマンドでイメージを作成していたが、これからは、gccコマンドでイメージを作成できる。
$ gcc -nostdlib -o helloos3.img -Tlnk.ls helloos3.s今まで通り、qemuで確認してOK。
$ qemu-system-i386 -m 32 -localtime -vga std -fda helloos3.imgここを参考にすると、リンカスクリプトを
OUTPUT_FORMAT("binary"); IPLBASE = 0x7c00; SECTIONS { . = IPLBASE; .text : {*(.text)} .data : {*(.data)} . = IPLBASE + 510; .sign : {SHORT(0xaa55)} }のように書くと 0x1FEからの0xAA,0x55も定義できるようだけど、試していない。
今のところ、.text, .dataの設定は不要だった。
そのうち必要になるのかな?
Z80のアセンブラには慣れているせいか、GASの標準であるAT&T構文ではsourceとdestinationが逆なのは、ちょっと気持ち悪く感じる。
参考
- BIOS interrupt call
- Gnu AS equivalent of ORG in NASM
- OS開発 BIOS・リアルモード
- 未来設計図 1日目の続き
- Handwriting OS自作入門 onLinux 2日目
0 件のコメント:
コメントを投稿