Google Go言語でOSを書く

表題の通り。

とりあえず挑戦してみようと思います。

  • -

実はコレ思いついたのが25日の夜で、

しかもオニャノコが
「クリスマス暇そうにしている君を救済してあげよう」
的に遊んでくれるらしくて、

その待ち合わせの時間つぶし中に思いついてしまいまして。


で、結局のところ、オニャノコと遊んでる間もずーっと頭から離れませんでした。
…ごめんなさい、嘘です。正直女の子の方が大s(ry

  • -

手順

  • gccgoをインストール
    • グーグル先生製のコンパイラ"8g"にはgccの-nostdincに相当するオプションがなかったので。
  • テストコードをコンパイル
  • コードの検証
  • -

gccgoをインストールする

実は…ムチャクチャ苦労しました。

Googleのサイト(http://golang.org/doc/gccgo_install.html)の手順にしたがって、subversionからチェックアウトしてきてmake -> make install


 $ svn checkout svn://gcc.gnu.org/svn/gcc/branches/gccgo gccgo
 $ mkdir objdir
 $ cd objdir
 $ ../gccgo/configure --enable-languages=c,c++,go --with-arch=i686
このconfigureの時に、32bit環境では--with-arch=i686オプションをつけると後でトラブルが起こらなさげ。
make installまで終わった後で、gccgoでコンパイルしようとすると次のように怒られたのですが、

/usr/local/gccgo/lib/gcc/i686-pc-linux-gnu/../../../libgo.so: undefined reference to '__sync_fetch_and_add8'
/usr/local/gccgo/lib/gcc/i686-pc-linux-gnu/../../../libgo.so: undefined reference to'__sync_fetch_and_add_4'
/usr/local/gccgo/lib/gcc/i686-pc-linux-gnu/../../../libgo.so: undefined reference to'__sync_bool_compare_and_swap_4'
    • with-arch=i686オプションをつけることで回避できました。

 $ make
(CoreDuo L2300で約3時間)
 $ make install
これでgccgoコマンドが使えるようになるので、ライブラリを指定
 $ LD_LIBRARY_PATH=/usr/local/lib
準備は整ったので適当にプログラム書く
 $ vim helloworld.go
内容は省略。ご想像にお任せします。
 $ gccgo helloworld.go
 $ ./a.out
helloworld。はい。おk。

テストコードをコンパイル

とにかくテストコードをコンパイルします。
OSを書く上で、とりあえずのところ

package main

func main(){
        var x,y int;
        x = 10;
        y = 20;
        x = x*y;
}

というような、どーでもいいコードにした。
(勿論、fmtとかインポートできないので。)

これをコンパイル。ただし-Wa,-aでアセンブルコードを吐かせ、-nostdincオプションをつけます。
本当は-nostdlibもつけたいのですが、つけられません。理由は後述。

$ gccgo -Wa,-a -nostdinc test.go

とりあえず何かしらバイナリは発生しました。

gccgoが吐く内容

とりあえず、GASが吐いたアセンブリコードを確認します。

   1              		.file	"test.go"
   2              		.section	.go_export,"",@progbits
   3 0000 76313B0A 		.ascii	"v1;\n"
   4 0004 7061636B 		.ascii	"package "
   4      61676520 
   5 000c 6D61696E 		.ascii	"main"
   6 0010 3B0A     		.ascii	";\n"
   7 0012 7072696F 		.ascii	"priority 1;\n"
   7      72697479 
   7      20313B0A 
   8 001e 66756E63 		.ascii	"func "
   8      20
   9 0023 2E6D6169 		.ascii	".main.main"
   9      6E2E6D61 
   9      696E
  10 002d 2028     		.ascii	" ("
  11 002f 29       		.ascii	")"
  12 0030 3B0A     		.ascii	";\n"
  13 0032 66756E63 		.ascii	"func "
  13      20
  14 0037 6D61696E 		.ascii	"main"
  15 003b 2028     		.ascii	" ("
  16 003d 29       		.ascii	")"
  17 003e 3B0A     		.ascii	";\n"
  18 0040 63686563 		.ascii	"checksum EE27AD2EBD84C7C09629DFC1F55FB5CF97BE84ED;\n"
  18      6B73756D 
  18      20454532 
  18      37414432 
  18      45424438 
  19              		.text
  20              	.globl main.main
  21              		.type	main.main, @function
  22              	main.main:
  23 0000 653B2530 		cmpl	%gs:48, %esp
  23      000000
  24 0007 730A     		jae	.L2
  25 0009 6A00     		pushl	$0
  26 000b 6A10     		pushl	$16
  27 000d E8FCFFFF 		call	__morestack
  27      FF
  28 0012 C3       		ret
  29              	.L2:
  30 0013 55       		pushl	%ebp
  31 0014 89E5     		movl	%esp, %ebp
  32 0016 83EC10   		subl	$16, %esp
  33 0019 C745FC00 		movl	$0, -4(%ebp)
  33      000000
  34 0020 C745F800 		movl	$0, -8(%ebp)
  34      000000
  35 0027 C745FC0A 		movl	$10, -4(%ebp)
  35      000000
  36 002e C745F814 		movl	$20, -8(%ebp)
  36      000000
  37 0035 8B45FC   		movl	-4(%ebp), %eax
  38 0038 0FAF45F8 		imull	-8(%ebp), %eax
  39 003c 8945FC   		movl	%eax, -4(%ebp)
  40 003f C9       		leave

GAS LISTING /tmp/ccQWzczF.s 			page 2


  41 0040 C3       		ret
  42              		.size	main.main, .-main.main
  43              	.globl __go_init_main
  44              		.type	__go_init_main, @function
  45              	__go_init_main:
  46 0041 653B2530 		cmpl	%gs:48, %esp
  46      000000
  47 0048 730A     		jae	.L4
  48 004a 6A00     		pushl	$0
  49 004c 6A00     		pushl	$0
  50 004e E8FCFFFF 		call	__morestack
  50      FF
  51 0053 C3       		ret
  52              	.L4:
  53 0054 55       		pushl	%ebp
  54 0055 89E5     		movl	%esp, %ebp
  55 0057 5D       		popl	%ebp
  56 0058 C3       		ret
  57              		.size	__go_init_main, .-__go_init_main
  58              		.ident	"GCC: (GNU) 4.5.0 20091110 (experimental)"
  59              		.section	.note.GNU-stack,"",@progbits
  60              		.section	.note.GNU-split-stack,"",@progbits

…。

……。汗汗;;。
CやC++の後続ーとか言うのでもっと綺麗なコード吐くのだと思ってましたが、全然いやいやそんなことなかった><;

とりあえず気になるのは50行目の call __morestack ですね。

gccgoでコンパイルする時に、-nostdlibオプションをつけるとコンパイルが通らないのですが、
はおそらくコイツが原因ですね。
これではOSは書けませんですよねー。困りました。

とりあえず今日は時間がないのでここまでですが、
morestackの仕事の調べはついているので、とりあえずダミーを作ってリンクし、-nostdlibをつけてコンパイルが通るかってのと、
コードセクション意外を殺せるのかを調べてみたいと思います。

正直、思ってたよりも難しそうです。あう。