# HG changeset patch # User mir3636 # Date 1538568410 -32400 # Node ID 1a23828953f2a80c078a79cbc802fc9e648d0e78 haribote day 4 diff -r 000000000000 -r 1a23828953f2 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,51 @@ +# target name +TARGET=ipl + +# dependencies +asmhead.bin : asmhead.asm + nasm -f elf32 -g -o asmhead.bin asmhead.asm +nasmfunc.o : nasmfunc.asm + nasm -f elf32 -g -o nasmfunc.o nasmfunc.asm +#bootpack.bin : bootpack.c nasmfunc.o +# gcc -m32 -nostdlib -Wl,--oformat,binary bootpack.c nasmfunc.o -T os.ls -o bootpack.bin +bootpack.o : bootpack.c + clang -target i386-pc-linux -c bootpack.c -o bootpack.o +bootpack.bin : bootpack.o nasmfunc.o + i386-elf-ld -m elf_i386 -e HariMain -o bootpack.bin -T os.ls bootpack.o nasmfunc.o +haribote.sys : asmhead.bin bootpack.bin + cat asmhead.bin bootpack.bin > haribote.sys +iplelf.bin : iplelf.asm + nasm -o iplelf.bin iplelf.asm +ipl10.bin : ipl10.asm + nasm -o ipl10.bin ipl10.asm +haribote.img : ipl10.bin haribote.sys + mformat -f 1440 -C -B ipl10.bin -i haribote.img :: + mcopy -i haribote.img haribote.sys :: +img : + make -r haribote.img + +kernel.elf: asmhead.bin bootpack.o nasmfunc.o + i386-elf-ld -m elf_i386 -e asmhead -o kernel.elf -T os.ls asmhead.bin bootpack.o nasmfunc.o + +elf.img : iplelf.bin kernel.elf + mformat -f 1440 -C -B iplelf.bin -i elf.img :: + mcopy -i elf.img kernel.elf :: + +clean: + -rm *.bin + -rm *.o + -rm *.sys + -rm *.img + +src_only : + make clean + rm haribote.img + +elf: elf.img kernel.elf + qemu-system-i386 -fda elf.img -m 512M + +elfd: elf.img kernel.elf + qemu-system-i386 -fda elf.img -m 512M -gdb tcp::1234 -S + +do: haribote.img + qemu-system-i386 -fda haribote.img -m 512M diff -r 000000000000 -r 1a23828953f2 asmhead.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/asmhead.asm Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,154 @@ +; haribote-os +; TAB=4 + + +BOTPAK EQU 0x00280000 ; bootpackのロード先 +DSKCAC EQU 0x00100000 ; ディスクキャッシュの場所 +DSKCAC0 EQU 0x00008000 ; ディスクキャッシュの場所(リアルモード) + +; BOOT_INFO関係 + CYLS EQU 0x0ff0 ; ブートセクタが設定する + LEDS EQU 0x0ff1 + VMODE EQU 0x0ff2 ; 色数に関する情報。何ビットカラーか? + SCRNX EQU 0x0ff4 ; 解像度のX(screen x) + SCRNY EQU 0x0ff6 ; 解像度のY(screen y) + VRAM EQU 0x0ff8 ; グラフィックバッファの開始番地 + +; ORG 0xc200 ; このプログラムがどこに読み込まれるのか + +section .text + + global asmhead + +asmhead: + + +; 画面モードを設定 + + MOV AL,0x13 ; VGAグラフィックス、320*200*8bitカラー + MOV AH,0x00 + INT 0x10 + MOV BYTE [VMODE],8 ; 画面モードをメモする + MOV WORD [SCRNX],320 + MOV WORD [SCRNY],200 + MOV DWORD [VRAM],0x000a0000 + +; キーボードのLED状態をBIOSに教えてもらう + + MOV AH,0x02 + INT 0x16 ; keyboard BIOS + MOV [LEDS],AL + +; PIC が一切の割り込みを受け付けないようにする +; AT互換機の仕様では、PICの初期化をするなら、 +; こいつをCLI前にやっておかないと、たまにハングアップする +; PICの初期化は後でやる + + MOV AL,0xff + OUT 0x21,AL + NOP ; OUT命令を連続させるとうまくいかない機種があるらしいので + OUT 0xa1,AL + + CLI ; さらにCPUレベルでも割り込み禁止 + +; CPUから1MB以上のメモリにアクセスできるように、A20GATEを設定 + + CALL waitkbdout + MOV AL,0xd1 + OUT 0x64,AL + CALL waitkbdout + MOV AL,0xdf ; enable A20 + OUT 0x60,AL + CALL waitkbdout + +; プロテクトモード移行 + +;[INSTRSET "i486p"] ; 486の命令まで使いたいという記述 + + LGDT [GDTR0] ; 暫定GDTを設定 + MOV EAX,CR0 + AND EAX,0x7fffffff ; bit31を0にする(ページング禁止のため) + OR EAX,0x00000001 ; bit0を1にする(プロテクトモード移行のため) + MOV CR0,EAX + JMP pipelineflush +pipelineflush: + MOV AX,1*8 + MOV DS,AX + MOV ES,AX + MOV FS,AX + MOV GS,AX + MOV SS,AX + +; bootpackの転送 + + MOV ESI,bootpack ; 転送元 + MOV EDI,BOTPAK ; 転送先 + MOV ECX,512*1024/4 + CALL memcpy + +; ついでにディスクデータも本来の位置へ転送 + +; まずはブートセクタから + + MOV ESI,0x7c00 ; 転送元 + MOV EDI,DSKCAC ; 転送先 + MOV ECX,512/4 + CALL memcpy + +; 残り全部 + + MOV ESI,DSKCAC0+512 ; 転送元 + MOV EDI,DSKCAC+512 ; 転送先 + MOV ECX,0 + MOV CL,BYTE[CYLS] + IMUL ECX,512*18*2/4 ; シリンダ数からバイト数/4に変換 + SUB ECX,512/4 ; IPLの分だけ差し引く + CALL memcpy + +; asmhead でしなければいけないことは全部し終わったので +; あとはbootpackに任せる + +; bootpack の起動 + + MOV EBX,BOTPAK + MOV ECX,[EBX+16] + ADD ECX,3 ; ECX += 3 + SHR ECX,2 ; ECX /= 4 + JZ skip ;転送すべきものがない + MOV ESI,[EBX+20] ; 転送元 + ADD ESI,EBX + MOV EDI,[EBX+12] ; 転送先 + CALL memcpy +skip: + MOV ESP,[EBX+12] ; スタック初期値 + JMP DWORD 2*8:0x0000001b + +waitkbdout: + IN AL,0x64 + AND AL,0x02 + JNZ waitkbdout ; AND の結果が0でなければwaitkbdoutへ + RET + +memcpy: + MOV EAX,[ESI] + ADD ESI,4 + MOV [EDI],EAX + ADD EDI,4 + SUB ECX,1 + JNZ memcpy ; 引き算した結果が0でなければmemcpy + RET +; memcpyはアドレスサイズプリフィクスを入れ忘れなければ、ストリング命令でも書ける + + ALIGNB 16,DB 0 +GDT0: + TIMES 8 DB 0 ; ヌルセクタ + DW 0xffff,0x0000,0x9200,0x00cf ; 読み書き可能セグメント32bit + DW 0xffff,0x0000,0x9a28,0x0047 ; 実行可能セグメント32bit (bootpack用) + + DW 0 +GDTR0: + DW 8*3-1 + DD GDT0 + + ALIGNB 16,DB 0 +bootpack: diff -r 000000000000 -r 1a23828953f2 bootpack.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootpack.c Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,15 @@ +extern void _io_hlt(void); +extern void _write_mem8(int addr, int data); + +void HariMain(void) { + int i; + + for (i = 0xa0000; i <= 0xaffff; i++) { + _write_mem8(i,i & 0x0f); + } + +fin: + _io_hlt(); //これでnasmfunc.asmのio_hltが実行される + goto fin; + +} diff -r 000000000000 -r 1a23828953f2 ipl10.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ipl10.asm Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,107 @@ +; hello-os +; TAB=4 + +CYLS EQU 10 ; どこまで読み込むか + + ORG 0x7c00 + +; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 + + JMP entry + DB 0x90 + + DB "HARIBOTE" + + DW 512 ; 1セクタの大きさ + DB 1 ; クラスタの大きさ + DW 1 ; FATがどこから始まるか + DB 2 ; FATの個数 + DW 224 ; ルートディレクトリの大きさ + DW 2880 ; このドライブの大きさ + DB 0xf0 ; メディアのタイプ + DW 9 ; FAT領域の長さ + DW 18 ; 1トラックに幾つのセクタがあるか + DW 2 ; ヘッドの数 + DD 0 ; パーティションを使ってここは必ず0 + DD 2880 ; このドライブの大きさをもう一度 + DB 0 ; physical disk number + DB 0 ; current head + DB 0x29 ; extended boot signature (0x29 means DOS 4.0 EBPB) + DD 0xffffffff ; ボリュームシリアルナンバー + DB "HARIBOTEOS " ; ディスクの名前11バイト + DB "FAT12 " ; フォーマットの名前 + + TIMES 18 DB 0 ; 18バイトあけておく + +; プログラム本体 +entry: + MOV AX,0 + MOV SS,AX + MOV SP,0x7c00 + MOV DS,AX + +; ディスクを読む + MOV AX,0x0820 + MOV ES,AX + MOV CH,0 ; シリンダ0 + MOV DH,0 ; ヘッド0 + MOV CL,2 ; セクタ2 +readloop: + MOV SI,0 ; 失敗回数を数えるレジスタ +retry: + MOV AH,0x02 ; AH=0x02 ディスク読み込み + MOV AL,1 ; 1セクタ + MOV BX,0 + MOV DL,0x00 ; Aドライブ + INT 0x13 ; ディスクBIOS呼び出し + JNC next ; エラーが起きなければnextへ + ADD SI,1 ; SIに1を足す + CMP SI,5 ; SIを5と比較 + JAE error ; SI >= 5だったらerrorへ + MOV AH,0x00 + MOV DL,0x00 ; Aドライブ + INT 0x13 ; ドライブのリセット + JMP retry +next: + MOV AX,ES ; アドレスを0x200進める + ADD AX,0x0020 + MOV ES,AX ; ADD ES,0x020 という命令がないのでこうしている + ADD CL,1 ; CLに1を足す + CMP CL,18 ; CLと18を比較 + JBE readloop ; CL<=18だったらreadloopへ + MOV CL,1 + ADD DH,1 + CMP DH,2 + JB readloop ; DH < 2 だったら readloop へ + MOV DH,0 + ADD CH,1 + CMP CH,CYLS + JB readloop ; CH < CYLS だったら readloop へ + +; 読み終わったのでharibote.sysを実行だ! + + MOV [0x0ff0],CH ; IPLがどこまで読んだかをメモ + JMP 0xc200 + +error: + MOV SI,msg +putloop: + MOV AL,[SI] ; SI番地の1バイトの内容をALに書き込む + ADD SI,1 + CMP AL,0 + JE fin + MOV AH,0x0e ; 一文字表示ファンクション + MOV BX,15 + INT 0x10 + JMP putloop +fin: + HLT + JMP fin +msg: + DB 0x0a, 0x0a ; 改行を2つ + DB "hello, world" + DB 0x0a + DB 0 + + TIMES 0x7dfe-0x7c00-($-$$) DB 0 ; 0x01ff までスキップ + DB 0x55, 0xaa ; boot signature diff -r 000000000000 -r 1a23828953f2 iplelf.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iplelf.asm Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,109 @@ +; hello-os +; TAB=4 + +CYLS EQU 10 ; どこまで読み込むか + + ORG 0x7c00 + +; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 + + JMP entry + DB 0x90 + + DB "HARIBOTE" + + DW 512 ; 1セクタの大きさ + DB 1 ; クラスタの大きさ + DW 1 ; FATがどこから始まるか + DB 2 ; FATの個数 + DW 224 ; ルートディレクトリの大きさ + DW 2880 ; このドライブの大きさ + DB 0xf0 ; メディアのタイプ + DW 9 ; FAT領域の長さ + DW 18 ; 1トラックに幾つのセクタがあるか + DW 2 ; ヘッドの数 + DD 0 ; パーティションを使ってここは必ず0 + DD 2880 ; このドライブの大きさをもう一度 + DB 0 ; physical disk number + DB 0 ; current head + DB 0x29 ; extended boot signature (0x29 means DOS 4.0 EBPB) + DD 0xffffffff ; ボリュームシリアルナンバー + DB "HARIBOTEOS " ; ディスクの名前11バイト + DB "FAT12 " ; フォーマットの名前 + + TIMES 18 DB 0 ; 18バイトあけておく + +; プログラム本体 +entry: + MOV AX,0 + MOV SS,AX + MOV SP,0x7c00 + MOV DS,AX + +; ディスクを読む + MOV AX,0x0800 + MOV ES,AX + MOV CH,0 ; シリンダ0 + MOV DH,0 ; ヘッド0 + MOV CL,2 ; セクタ2 +readloop: + MOV SI,0 ; 失敗回数を数えるレジスタ +retry: + MOV AH,0x02 ; AH=0x02 ディスク読み込み + MOV AL,1 ; 1セクタ + MOV BX,0 + MOV DL,0x00 ; Aドライブ + INT 0x13 ; ディスクBIOS呼び出し + JNC next ; エラーが起きなければnextへ + ADD SI,1 ; SIに1を足す + CMP SI,5 ; SIを5と比較 + JAE error ; SI >= 5だったらerrorへ + MOV AH,0x00 + MOV DL,0x00 ; Aドライブ + INT 0x13 ; ドライブのリセット + JMP retry +next: + MOV AX,ES ; アドレスを0x200進める + ADD AX,0x0020 + MOV ES,AX ; ADD ES,0x020 という命令がないのでこうしている + ADD CL,1 ; CLに1を足す + CMP CL,18 ; CLと18を比較 + JBE readloop ; CL<=18だったらreadloopへ + MOV CL,1 + ADD DH,1 + CMP DH,2 + JB readloop ; DH < 2 だったら readloop へ + MOV DH,0 + ADD CH,1 + CMP CH,CYLS + JB readloop ; CH < CYLS だったら readloop へ + +; 読み終わったのでharibote.sysを実行だ! + + MOV [0x0ff0],CH ; IPLがどこまで読んだかをメモ +; MOV SI,0xd000+0x18 ; ELF entry point offset +; MOV AX,[SI] + JMP 0xd190 + +error: + MOV SI,msg +putloop: + MOV AL,[SI] ; SI番地の1バイトの内容をALに書き込む + ADD SI,1 + CMP AL,0 + JE fin + MOV AH,0x0e ; 一文字表示ファンクション + MOV BX,15 + INT 0x10 + JMP putloop +fin: + HLT + JMP fin +msg: + DB 0x0a, 0x0a ; 改行を2つ + DB "hello, world" + DB 0x0a + DB 0 + + TIMES 0x7dfe-0x7c00-($-$$) DB 0 ; 0x01ff までスキップ + DB 0x55, 0xaa ; boot signature diff -r 000000000000 -r 1a23828953f2 nasmfunc.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nasmfunc.asm Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,22 @@ +; nasmfunc +; TAB=4 + +;[FORMAT "WCOFF"] ; オブジェクトファイルを作るモード +bits 32 ; 32ビットモード用の機械語を作らせる + +global _io_hlt ; このプログラムに含まれる関数名 +global _write_mem8 + +; 以下は実際の関数 + +section .text ; オブジェクトファイルはこれを書いてからプログラムを書く + +_io_hlt: ; void io_hlt(void); + HLT + RET + +_write_mem8: + MOV ECX,[ESP+4] ; [ESP+4]にaddr が入っているのでそれをECXに読み込む + MOV AL,[ESP+8] ; [ESP+8]にdataが入っているのでそれをALに読み込む + MOV [ECX],AL + RET diff -r 000000000000 -r 1a23828953f2 os.ls --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os.ls Wed Oct 03 21:06:50 2018 +0900 @@ -0,0 +1,30 @@ +/* os.ls */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(asmhead) + +SECTIONS { + .head 0x0 : { + LONG(64 * 1024) /* 0 : size(stack+.data+heap) */ + LONG(0x69726148) /* 4 : "Hari" */ + LONG(0) /* 8 : mmarea*/ + LONG(0x310000) /* 12 : stack初期値 & .data転送先 */ + LONG(SIZEOF(.data)) /* 16 : size of .data */ + LONG(LOADADDR(.data)) /* 20 : size of .data */ + LONG(0xE9000000) /* 24 : E9000000 */ + LONG(HariMain - 0x20) /* 28 : entry - 0x20 */ + LONG(0) /* 32 : heap領域開始アドレス */ + } + + . = 0xd18d; + +.text : {*(.text)} + + .data 0x310000 : AT ( ADDR(.text) + SIZEOF(.text) ) { + *(.data) + *(.rodata*) + *(.bss) + } + + /DISCARD/ : { *(.eh_frame) } +}