30日でできる!OS自作入門を Linux & GAS で行う (2日目)

というわけで、どうみても前の更新から5日以上たっているけれども2日目の説明を(笑
2日目で行うことは、

  1. 1日目で .byte、.word、.intでバイナリ直打ちしていた箇所をプログラムに置き換える
  2. リンカスクリプトを書く。
  3. Makefileアセンブルとディスクイメージ作成を自動化する

という3点である。1は、OS自作本を見ればなんとなくできてしまうだろう。また、3についても、 Linux 上でプログラム経験がある方であれば、あまり難しくないだろう。問題は2である。ユーザランドプログラムを書く用途でgccを使っていると、自分でリンカスクリプトを書く機会はなかなかない。せっかくなので、これを機にリンカスクリプトを書いてみよう(ToDo:説明増やす。今は寝る)。

  1 OUTPUT_FORMAT(binary)
  2 
  3 OUTPUT_ARCH(i386)
  4 
  5 SECTIONS {
  6 . = 0x7c00;
  7 .text : { *(.text) }
  8 }
  9 

このリンカスクリプトを使ってバイナリを生成するには、 -T オプションを使う。

 ld (入力オブジェクトファイル名) -T (リンカスクリプト) -o (出力するバイナリ)

うまくいくと、1日目と変わらない起動画面が出てくる。

というわけで、詳細についてはソースコードとOS自作本を見て頑張ってほしい。君ならできるはず!
ソースコードはこちら
Makefile

  1 IMG=helloos.img
  2 IPL=ipl.bin
  3 
  4 all: ipl.s
  5         make ipl
  6         make img
  7         make run
  8 
  9 img: $(IPL)
 10         mformat -f 1440 -C -B $(IPL) -i $(IMG) ::
 11 
 12 ipl: $(IPL:%.bin=%.o)
 13         ld $^  -T binary.ls -o $(IPL)
 14 
 15 run: $(IMG)
 16         qemu -m 32 -localtime -std-vga -hda ./$(IMG)
 17 
 18 clean:
 19         rm -f $(IMG) $(IPL) $(IPL:%.bin=%.o)
 20 

ipl.s

  1 // hello-os ver.gas
  2 // This program is going to be loaded at 0x7c00
  3 
  4 // $base_address = 0x7c00
  5 base_address:
  6     .code16
  7 
  8     jmp entry
  9     .byte   0x90
 10     .ascii  "HelloIpl"
 11     .word   512
 12     .byte   1
 13     .word   1
 14     .byte   2
 15     .word   224
 16     .word   2880
 17     .byte   0xf0
 18     .word   9
 19     .word   18
 20     .word   2
 21     .int    0
 22     .int    2880
 23     .byte   0,0,0x29
 24     .int    0xffffffff
 25     .ascii  "HELLO-OS   "
 26     .ascii  "FAT12   "
 27     .skip   18,0
 28 
 29 entry:
 30     movw    $0,%ax
 31     movw    %ax,%ss
 32     movw    $base_address,%sp
 33     movw    %ax,%ds
 34     movw    %ax,%es
 35 
 36     // label のアドレスをさすには、$msgとする
 37     movw    $msg,%si
 38 
 39     // 間違いなくアドレッシングがおかしい
 40     // siレジスタのさしている先がおかしい
 41     // $ つけわすれだった ;_;
 42 putloop:
 43     movb    (%si),%al
 44     add     $0x01,%si
 45     cmpb    $0x00,%al
 46     je      fin
 47     movb    $0x0e,%ah
 48     movw    $0x0015,%bx
 49     int     $0x10
 50     jmp     putloop
 51 
 52 fin:
 53     hlt
 54     jmp     fin
 55 
 56 msg:
 57     .byte   0x0a,0x0a
 58     .ascii  "hello,world"
 59     .byte   0x0a
 60     .byte   0x00
 61 
 62     .org    0x1fe
 63     .byte   0x55,0xaa