2010-04-04
32bit Protect Mode
ようやく完全に32bitに移行できたので、その記録。
まずは、IPL。
.code16gcc _start: JMP entry // for FAT12 .byte 0x90 .ascii "HelloIpl" .word 512 .byte 1 .word 1 .byte 2 .word 224 .word 2880 .byte 0xf0 .word 9 .word 18 .word 2 .int 0 .int 2880 .byte 0,0,0x29 .int 0xffffffff .ascii "HELLO-OS " .ascii "FAT12 " .skip 18,0 entry: // レジスタの初期化 movw $0x0, %ax movw %ax, %ss movw %ax, %dx movw %ax, %ds movw %ax, %es // 0x7c00に読み込まれるので、SPを0x7c00にしないとアドレスの // 設定が煩雑になるため。 movw $0x7c00, %sp // フロッピーディスクを読み込む // 読み込む先を設定する。 movw $0x0820, %ax movw %ax, %es // シリンダ0 ヘッド0 セクタ2 movb $0x0, %ch movb $0x0, %dh movb $0x02, %cl //10シリンダ分読み込む readloop: // エラーカウンター movw $0x00, %si retry: //Disk読み出しのBIOSコール movb $0x02, %ah movb $0x01, %al movw $0x00, %bx movb $0x00, %dl int $0x13 jnc next //エラー処理 addw $0x01, %si // retry5回でエラー終了 cmp $0x05, %si jae error // ドライブを初期化 mov $0x00, %ah mov $0x00, %dl jmp retry next: //格納場所のアドレスを0x0020進める movw %es, %ax addw $0x0020, %ax movw %ax, %es add $0x01, %cl cmp $18, %cl jbe readloop movb $0x01, %cl addb $0x01, %dh cmp $0x02, %dh jb readloop movb $0x01, %dh add $0x01, %ch cmpb $10, %ch jb readloop // カーネルイメージが、読み込まれている // アドレスにジャンプする jmp 0x00c200 fin: hlt jmp fin error: movw $err_msg, %si call printstr jmp fin printstr: nop putloop: // SIで指定された文字列を // 1文字ずつ取り出す。 movb (%si), %al addw $0x01, %si // NULL文字か比較 cmpb $0x00, %al je putloop_end // SystemCallの設定 movb $0x0E, %ah movw $0x0015, %bx int $0x10 jmp putloop putloop_end: ret err_msg: .byte 0x0a,0x0a .ascii "Disk Error\r\n" .byte 0x00 .org 0x1fe .byte 0x55,0xaa
iplである程度、kernelに相当する部分をメモリ上に読み込んでおく。
.code16
.global _start
_start:
// レジスタを初期化する
movw $0x00, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
// 32ビットモードを有効にするために
// PICをマスクする
movb $0xff, %al
outb %al, $0x21
nop
outb %al, $0xa1
// 割り込みフラグをクリア
cli
// A20Gateを有効にする。
//割り込みを禁止する
call waitkbout
movb $0xd1, %al
outb %al, $0x64
call waitkbout
movb $0xdf, %al
outb %al, $0x60
call waitkbout
.arch i486
to_protect:
// Protectモードにする
lgdtl (gtr0)
movl %cr0, %eax
and $0x7ffffff, %eax
or $0x0000001, %eax
movl %eax, %cr0
jmp pipelineflash
pipelineflash:
movw $0x8, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
// osmainを0x00280000にコピー
movl $osmain, %esi
movl $0x00280000, %edi
movl $512 * 1024 / 4, %ecx
call _memcpy
jmp $0x10, $0x00000001
_fin:
hlt
jmp _fin
waitkbout:
inb $0x64, %al
andb $0x02, %al
jnz waitkbout
ret
// Memory Copy
// Source : esi
// Destination: edi
// Counter: ecx
_memcpy:
movl (%esi), %eax
add $4, %esi
movl %eax, (%edi)
add $4, %edi
sub $1, %ecx
jnz _memcpy
ret
.align 8
gdt0:
// GlobalDescriptor Table
// Null Selecter
.skip 8, 0x00
// 1st GDT
.word 0xffff, 0x0000, 0x9200, 0x00cf
// 2nd GDT
.word 0xffff, 0x0000, 0x9a28, 0x0047
// Last GDT
.word 0x0000
gtr0:
.word 8 * 3 - 1
.int gdt0
osmain:
nop
hlt
jmp osmain
動作確認には、bochsを利用。
00442040000i[CPU0 ] CPU is in protected mode (halted) 00442040000i[CPU0 ] CS.d_b = 32 bit 00442040000i[CPU0 ] SS.d_b = 32 bit 00442040000i[CPU0 ] EFER = 0x00000000 00442040000i[CPU0 ] | RAX=0000000000000000 RBX=0000000000000015 00442040000i[CPU0 ] | RCX=0000000000000000 RDX=0000000000000100 00442040000i[CPU0 ] | RSP=0000000000007c00 RBP=0000000000000000 00442040000i[CPU0 ] | RSI=000000000008c2a8 RDI=0000000000300000 00442040000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000 00442040000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000 00442040000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000 00442040000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000 00442040000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf ZF af PF cf 00442040000i[CPU0 ] | SEG selector base limit G D 00442040000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D 00442040000i[CPU0 ] | CS:0010( 0002| 0| 0) 00280000 0007ffff 0 1 00442040000i[CPU0 ] | DS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 00442040000i[CPU0 ] | SS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 00442040000i[CPU0 ] | ES:0008( 0001| 0| 0) 00000000 ffffffff 1 1 00442040000i[CPU0 ] | FS:0008( 0001| 0| 0) 00000000 ffffffff 1 1 00442040000i[CPU0 ] | GS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
で、どこでハマっていたかというと、far jmpするところ。far jmpがうまくいかずにコードセグメントがなかなか32bitになってくれませんでした。
トラックバック - http://d.hatena.ne.jp/kawa1128/20100404/1270361566
リンク元
- 57 http://www.google.co.jp/search?q=Could+not+find+apk!&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja-JP-mac:official&hl=ja&client=firefox-a
- 25 http://diaspar.jp/node/251
- 25 http://www.google.co.jp/
- 19 http://www.hammer-and-a-nail.net/20091128200733/
- 17 http://twitter.com/kawa1128
- 10 http://www.kawa1128.jp/profile.html
- 9 http://www.kawa1128.jp/
- 8 http://www.google.co.jp/search?hl=ja&q=Error+generating+final+archive&btnG=検索&lr=lang_ja&aq=f&aqi=&aql=&oq=&gs_rfai=
- 8 http://www.google.co.jp/search?hl=ja&source=hp&q=Could+not+find+.apk!&lr=&aq=f&aqi=&aql=&oq=&gs_rfai=
- 8 http://www.google.co.jp/search?q=error+generating+final+archive&hl=ja&lr=lang_ja&ei=jQ7RS82lJIuTkAW7_7WpDA&sa=X&oi=lrtip&ct=restrict&cad=8&ved=0CAcQuAE


