Hatena::ブログ(Diary)

big-eyed-hamsterの日記

2009-01-06

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日目と変わらない起動画面が出てくる。

f:id:big-eyed-hamster:20081230055038j:image

というわけで、詳細についてはソースコード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

YUDYYUDY 2009/06/28 21:39 僕もOS自作にハマっているんですが、リンカスクリプトなんて便利なものがあるとは・・!参考になりました

big-eyed-hamsterbig-eyed-hamster 2009/07/05 05:16 > YUDYさん
コメントありがとうございます。すごく適当な記事ですが、お役にたてたのなら幸いです:D

ぬっちぬっち 2011/09/07 19:18 はじめまして。Linux環境でのOS開発を行おうと思っているので、大変参考になります。
ところで私の環境では、ldコマンドが
i386:x86-64 architecture of input file `ipl.o' is incompatible with i386 output
というエラーで怒られ、先に進まないのです。。。
64bitの環境で行っているのが問題なのかな・・・。

ぬっちぬっち 2011/09/08 21:27 無事解決したようです。
オブジェクトファイルが64bitのものだったようなので、asに--32オプションをつけて作成したファイルを使うことで起動できました。
お騒がせして申し訳ございません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/big-eyed-hamster/20090106/1231182085
Connection: close