From e07976b35871aaf7182edb0a6ab816bcbbd3bf1a Mon Sep 17 00:00:00 2001 From: k-masatany Date: Sun, 3 Sep 2017 23:27:39 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[WIP]=20=E3=82=AD=E3=83=BC=E3=83=9C?= =?UTF-8?q?=E3=83=BC=E3=83=89=E5=85=A5=E5=8A=9B=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 3bf64046273b94a153b5546f7e2869bfff3b9a42 Mon Sep 17 00:00:00 2001 From: k-masatany Date: Sun, 3 Sep 2017 23:37:39 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E3=81=A8=E3=82=8A=E3=81=82=E3=81=88?= =?UTF-8?q?=E3=81=9A=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/devices/keyboard.rs | 0 src/devices/mod.rs | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/devices/keyboard.rs diff --git a/src/devices/keyboard.rs b/src/devices/keyboard.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/devices/mod.rs b/src/devices/mod.rs index 5c9e0da..876d372 100644 --- a/src/devices/mod.rs +++ b/src/devices/mod.rs @@ -1 +1,2 @@ -pub mod crt; \ No newline at end of file +pub mod crt; +pub mod keyboard; \ No newline at end of file From adac561f1160dfe13efbb1f203b321b27e835e1e Mon Sep 17 00:00:00 2001 From: k-masatany Date: Mon, 2 Oct 2017 16:16:43 +0900 Subject: [PATCH 3/3] =?UTF-8?q?bootloader=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bootsector.asm | 152 +++++++++++++++++++++++++++++++++++++++++++++ lib/bootsector.bin | Bin 0 -> 512 bytes lib/secondboot.asm | 142 ++++++++++++++++++++++++++++++++++++++++++ lib/secondboot.bin | Bin 0 -> 272 bytes 4 files changed, 294 insertions(+) create mode 100644 lib/bootsector.asm create mode 100644 lib/bootsector.bin create mode 100644 lib/secondboot.asm create mode 100644 lib/secondboot.bin diff --git a/lib/bootsector.asm b/lib/bootsector.asm new file mode 100644 index 0000000..9c626b8 --- /dev/null +++ b/lib/bootsector.asm @@ -0,0 +1,152 @@ +;;; IPL program (ipl.asm) +;;; For x86 Architecture +;;; @author k-masatany + + ORG 0x7c00 + + ;; #define + cyls equ 0x0a ; 何シリンダ目まで読み込むかの設定 + +START: + jmp INIT ; 3 byte code(naskだと2バイトになるので注意) + + ;; FAT12BPB +FAT12: + db "rusternel" ; OS名 + dw 512 ; 1セクタあたりのバイト数 + db 1 ; 1クラスあたりのセクタ数 + dw 1 ; 予約セクタ + db 2 ; FATのテーブルの数 + dw 224 ; ルートディレクトリの長さ + dw 2880 ; 全セクタ数 + db 0xF0 ; メディアの種類 + dw 9 ; FAT1つの長さ(セクタ単位) + dw 18 ; 1トラックあたりのセクタの数 + dw 2 ; ドライブのヘッドの数 + dd 0 ; 他のパーティションのブートセクタの位置(0ならなし) + dd 2880 ; 全セクタ数(2880か0を指定) + db 0 ; ドライブ番号 + db 0 ; 予約(WindowsNTで使用) + db 0x29 ; 以下の3項目があることを示す + + dd 0xffffffff ; ボリュームシリアル番号 + db 'rusternel ' ; ボリュームラベル + db 'FAT12 ' ; ファイルシステム名 + times 18 db 0 ; 18バイト空けておく + + ;; 一連の初期化処理 +INIT: + ;; セグメントレジスタを初期化(全て0x0000 = csに設定 ) + mov ax,cs + mov ds,ax ; データセグメント初期化 + mov es,ax ; エクストラセグメン初期化 + mov ss,ax ; スタックセグメント初期化 + + ;; スタックポインタ初期化(0x7c00に設定) + ;; SPは0x7c00にしないと正常に動かない(原因は調査中) + mov sp,0x7c00 + + ;; ディスク読み込みの初期化 +DISK_INI: + mov si,loadimg + call PRINT + + mov ax,0x0820 ; 読み込んだデータをセグメントアドレス0x0820に展開 + mov es,ax + mov ch,0 ; シリンダ0 + mov dh,0 ; ヘッド0 + mov cl,2 ; セクタ2 + mov dl,0x00 ; Aドライブ + mov bx,0x0000 ; オフセットアドレスを0に設定 + +READLOOP: + mov si,0 ; 失敗回数を数えるレジスタsiを初期化 + +RETRY: + mov ah,0x02 + mov al,1 ; 1セクタ読み込み + int 0x13 ; ディスク関連ファンクション呼出 + jnc NEXT ; cf=0(エラー未発生)ならNEXTへ + + ;; 失敗した場合 + add si,1 + cmp si,5 + jae ERROR ; 5回失敗したら、エラー + + ;; ドライブのリセット + mov ah,0x00 + int 0x13 + jmp RETRY + +NEXT: + ;; セグメントアドレスを0x200(512バイト)進める + mov ax,es + add ax,0x0020 + mov es,ax + + add cl,1 ; セクタを1進める + + ;; 18セクタ読み込んだか + cmp cl,18 + jbe READLOOP + + add dh,1 ; ヘッド1へ + mov cl,1 ; セクタ1から読み込み + + ;;裏表読み込んだか + cmp dh,2 + jb READLOOP + + + add ch,1 ; シリンダを1進める + mov dh,0 ; ヘッド0から読み込み + + ;; 10シリンダ目まで読み込んだか + cmp ch,cyls + jb READLOOP + +READ_SETUP: + mov ax,0x0000 + mov es,ax ; もう一度esを初期化(もとの状態にもどす) + + mov si,complete + call PRINT + + mov [0x0ff0],ch ; 何シリンダ目まで読み込んだかメモ + + jmp 0xc200 + + jmp FIN ; ジャンプに失敗したとき用 + +ERROR: + mov si,error_mes + call PRINT + +FIN: + HLT + jmp FIN + + ;; 文字出力ルーチン +PRINT: + lodsb ; siで指定されたアドレスから1バイト取り出しalに格納 + cmp al,0 + je PRINTED ; 文末まで来たらPRINTEDへ + + mov ah,0x0e ; 1文字書き込みモード + mov bx,0x0007 + int 0x10 + + jmp PRINT + +PRINTED: + ret ; 呼出し元へ戻る + + ;; 文字データ +STRING_DATA: + loadimg db 'Loading image...', 0x0d,0x0a,0x00 ; 最後は、CR+LF+NULL + complete db 'Loading complete!', 0x0d,0x0a,0x00 + error_mes db 'Loading error.', 0x0d,0x0a,0x00 + + times 512 - 2 - ($-$$) db 0 ; 残りのバイトを0で埋める + + dw 0xAA55 ; ブートシグニチャ diff --git a/lib/bootsector.bin b/lib/bootsector.bin new file mode 100644 index 0000000000000000000000000000000000000000..732ca9c2aac97194c18c6616dfebdcba5d5658b7 GIT binary patch literal 512 zcmaFuS5#VDl3J9Pn!~`v$jHF-fWd+L11EzJ0}}%XIBe~OdJZ%nQ0P0*aFDU#r%>6AhGUEy85{mF6`gB1%D9c8;V)OwksS;S zeFyfvsd*v9(4qH%|D~hrYqot1wJ(?%zP$ds#)hGUa|_>Yc80S8uRk63$xlql%u83u n%uP&B)zj1C5V{HgugYX1 literal 0 HcmV?d00001 diff --git a/lib/secondboot.asm b/lib/secondboot.asm new file mode 100644 index 0000000..89e02fa --- /dev/null +++ b/lib/secondboot.asm @@ -0,0 +1,142 @@ +;;; For x86 Architecture +;;; @author k-masatany + + org 0xc200 + +INITOS EQU 0x00280000 ; OS本体部分の転送アドレス +DSKCAC EQU 0x00100000 ; キャッシュのアドレス +DSKCAC0 EQU 0x00008000 ; キャッシュのアドレス(iplが転送したもの) +VRAM EQU 0x000B8000 ; グラフィックバッファ(テキストモード)の開始番地 + +;;; BOOTINFO関連 +CYLS EQU 0x0ff0 ; 読み込んだシリンダ数を記録(iplが書き込んだ) +LEDS EQU 0x0ff1 + +; テキストモード固定 + mov al, 0x03 + mov ah, 0x00 + int 0x10 + +keystatus: + ;; キーボードの状態を取得 + mov ah,0x02 + int 0x16 + mov [LEDS],al ; LED点灯状態をメモ + + ;; PICが一切の割り込みを受け付けないようにする + mov al,0xff + out 0x21,al ; io出力 + nop ; out命令を連続させるとうまくいかない機種があるため + cli ; CPUレベルでも割り込み禁止 + + ;; A20GATE信号線をONにする(1MB以上のメモリにアクセスするため) + call waitkbdout ; 制御命令を受けられるまで待つ + mov al,0xd1 ; 0xd1 = キーボードコントローラのおまけ出力ポートに出力 + out 0x64,al ; 0x64 = PORT_KEYCMD + + call waitkbdout ; 制御命令を受けられるまで待つ + mov al,0x1f ; 0x1f : A20信号線をONにするための設定 + out 0x60,al ; 0x60 = PORT_KEYDAT + + call waitkbdout ; A20GATEの設定が終わるまで待つ + + ;; プロテクトモードに移行 + + lgdt [GDTR0] ; 暫定GDTを設定 + + mov eax,cr0 + and eax,0x7fffffff ; bit31を0にする(ページングを禁止するため) + or eax,0x00000001 ; bit0を1にする(プロテクトモードへ移行) + mov cr0,eax + + jmp pipelineflush ; パイプラインに先読みした命令をリセット + +pipelineflush: + ;; セグメントレジスタの値を設定しなおす(0x0008に設定) + mov ax,1*8 ; 2つ目のセグメント(gdt + 1) = 0x0000 + 1 * 8 + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + + ;; os本体の転送 + mov esi,initOS ; 転送元 + mov edi,INITOS ; 転送先 + mov ecx,512*1024/4 ; 512キロバイト(512*1024)を4で割る(ダブルワード単位なので) + call memcpy + + ;; ディスクデータを転送 + ;; まずはipl部分の転送 + mov esi,0x7c00 ; 転送元 + mov edi,DSKCAC ; 転送先 + mov ecx,512/4 ; 512バイト転送 + call memcpy + + ;; 残りのディスクキャッシュを転送 + mov esi,DSKCAC0+512 ; 転送元 + mov edi,DSKCAC+512 ; 転送先 + mov ecx,0 + mov cl,BYTE [CYLS] ; シリンダ数を読み込み + IMUL ecx,512*18*2/4 ; 1シリンダ分の大きさ(512バイト*18セクタ*2ヘッド分)*10シリンダ(ecxに格納) + sub ecx,512/4 ; iplの分だけ引く + call memcpy + + ;; .dataの領域を確保 + mov ebx,INITOS + mov ecx,[ebx+16] ; .dataセクションのサイズを代入 + add ecx,3 ; ecx += 3 + shr ecx,2 ; ecx /= 4(右に2桁シフト->1桁シフトで半分になる)=>転送するサイズ + jz skip ; .dataセクションの有無を確認(セクションがあれば.data領域を確保) + mov esi,[ebx+20] ; .dataセクションのファイル内の相対アドレス + add esi,ebx ; 転送元(ファイルから転送されたructiss.sysの.dataセクション) + mov edi,[ebx+12] ; 転送先(.data転送先とスタック領域の境目) + call memcpy + +skip: + ;; initOSに制御を移す + mov esp,[ebx+12] ; スタックポインタを設定(.data転送先とスタック領域の境目) + jmp DWORD 2*8:0x0000001b ; .sysのヘッダのjmp命令のある場所へジャンプ(2番目のセグメントの0x001bへジャンプ) + +fin: + hlt + jmp fin + +;;; サブルーチン関係 +waitkbdout: + in al,0x64 ; 装置番号0x64から読み込み + and al,0x02 ; 下から2ビット目の以外はマスク + in al,0x60 ; から読みして受信バッファからキーボードに溜ってるデータを出す + jnz waitkbdout ; 下から2ビット目が0 + ret + +memcpy: + mov eax,[esi] + add esi,4 + + mov [edi],eax + add edi,4 + + sub ecx,1 + jnz memcpy + + ret + + ALIGNB 16,DB 0 ; GDT0のラベルのアドレスが8の倍数になるように、キリのよいところまでDB 0で埋める + +;;; 定数 +GDT0: + times 8 DB 0 ; ヌルセレクタ(gdtの0番) + DW 0xffff,0x0000,0x9200,0x00cf ; 1番(asmhead用,読み書き可能セグメント) + DW 0xffff,0x0000,0x9a28,0x0047 ; 2番(osmain用,実行可能セグメント) + + DW 0 + +GDTR0: + DW 8*3-1 ; lgdt命令でレジスタに転送されるGDTのテーブルサイズ + DD GDT0 ; lgdt命令でレジスタに転送されるGDTの先頭アドレス + + ALIGNB 16,DB 0 + +;;; os本体へのラベル +initOS: diff --git a/lib/secondboot.bin b/lib/secondboot.bin new file mode 100644 index 0000000000000000000000000000000000000000..ddef4ff263e6fdb53a39d5b0b8ca7a60674e8152 GIT binary patch literal 272 zcmdnMyoKScz!s*nVv9cVZ}|UAal)?`I~X=xe3tTJBf|#yX9+J>G4L~raUJGYIFP3L z|NsB`wB{3x{7MI2Gwk4C=)2K(pzlH7i@pnK`veX%Fr@8gV9;Pl+sVMd#PFhuA#EQ+ z4Mb1?DA>Tj!0;j!B-jKNWC95S#TdHyKJceyo@5XL3OBw4E3;!r+YL4