30日でできる!OS自作入門を Linux & GAS で行う (2日目)
というわけで、どうみても前の更新から5日以上たっているけれども2日目の説明を(笑
2日目で行うことは、
という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