OSDN Git Service

MochiBooterの大幅改造(ATA-PIOreadによるカーネルロード)、VMイメージ作成ツール追加など
authorMochi <master.c.mochi@gmail.com>
Tue, 11 Jul 2017 14:53:50 +0000 (23:53 +0900)
committerMochi <master.c.mochi@gmail.com>
Tue, 11 Jul 2017 14:53:50 +0000 (23:53 +0900)
50 files changed:
build/Makefile
build/ptable.bin [deleted file]
src/Makefile
src/booter/Debug/DebugInit.c [new file with mode: 0644]
src/booter/Debug/DebugLog.c [new file with mode: 0644]
src/booter/Debug/DebugLog.h [new file with mode: 0644]
src/booter/Driver/DriverA20.c [new file with mode: 0644]
src/booter/Driver/DriverAta.c [new file with mode: 0644]
src/booter/Driver/DriverAta.h [new file with mode: 0644]
src/booter/Driver/DriverInit.c [new file with mode: 0644]
src/booter/InitCtrl/InitCtrlInit16.s [moved from src/booter/Initctrl/InitctrlCpu.s with 68% similarity]
src/booter/InitCtrl/InitCtrlInit32.c [new file with mode: 0644]
src/booter/Initctrl/InitctrlA20.s [deleted file]
src/booter/Initctrl/InitctrlMain.s [deleted file]
src/booter/IntMng/IntMngHdl.c [new file with mode: 0644]
src/booter/IntMng/IntMngHdl.h [new file with mode: 0644]
src/booter/IntMng/IntMngIdt.c [new file with mode: 0644]
src/booter/IntMng/IntMngIdt.h [new file with mode: 0644]
src/booter/IntMng/IntMngInit.c [new file with mode: 0644]
src/booter/IntMng/IntMngPic.c [new file with mode: 0644]
src/booter/IntMng/IntMngPic.h [new file with mode: 0644]
src/booter/Ipl/IplMain.s
src/booter/LoadMng/LoadMngInit.c [new file with mode: 0644]
src/booter/LoadMng/LoadMngInit.h [new file with mode: 0644]
src/booter/LoadMng/LoadMngKernel.c [new file with mode: 0644]
src/booter/Loader/LoaderLoad.s [deleted file]
src/booter/Makefile
src/booter/booter-main.lds
src/booter/include/Cmn.h [new file with mode: 0644]
src/booter/include/Debug.h [new file with mode: 0644]
src/booter/include/Driver.h [new file with mode: 0644]
src/booter/include/IntMng.h [new file with mode: 0644]
src/booter/include/LoadMng.h [new file with mode: 0644]
src/include/MLib/Basic/MLibBasic.h
src/include/hardware/ATA/ATA.h [new file with mode: 0644]
src/include/hardware/I8254/I8254.h [moved from src/kernel/include/hardware/I8254/I8254.h with 100% similarity]
src/include/hardware/I8259A/I8259A.h [moved from src/kernel/include/hardware/I8259A/I8259A.h with 100% similarity]
src/include/hardware/IA32/IA32.h [moved from src/kernel/include/hardware/IA32/IA32.h with 100% similarity]
src/include/hardware/IA32/IA32Descriptor.h [moved from src/kernel/include/hardware/IA32/IA32Descriptor.h with 100% similarity]
src/include/hardware/IA32/IA32Instruction.h [moved from src/kernel/include/hardware/IA32/IA32Instruction.h with 92% similarity]
src/include/hardware/IA32/IA32Paging.h [moved from src/kernel/include/hardware/IA32/IA32Paging.h with 100% similarity]
src/include/hardware/IA32/IA32Tss.h [moved from src/kernel/include/hardware/IA32/IA32Tss.h with 100% similarity]
src/include/hardware/Vga/Vga.h [moved from src/kernel/include/hardware/Vga/Vga.h with 100% similarity]
src/include/kernel/MochiKernel.h
src/kernel/Makefile
src/kernel/ProcMng/ProcMngElf.c
src/libraries/Makefile
src/tools/Makefile [new file with mode: 0644]
src/tools/makedisk/Makefile [new file with mode: 0644]
src/tools/makedisk/makedisk.c [new file with mode: 0644]

index 13143fc..42a52dc 100644 (file)
@@ -1,7 +1,7 @@
 #******************************************************************************#
 #* build/Makefile                                                             *#
-#*                                                                 2016/12/05 *#
-#* Copyright (C) 2016 Mochi                                                   *#
+#*                                                                 2017/07/11 *#
+#* Copyright (C) 2016-2017 Mochi                                              *#
 #******************************************************************************#
 #******************************************************************************#
 #* マクロ設定                                                                 *#
@@ -9,9 +9,6 @@
 # ディスクイメージファイル
 IMG_NAME    = mochi.img
 
-# パーティションテーブル
-PTABLE      = ptable.bin
-
 # ループデバイス
 LOOP_DEV    = /dev/loop0
 LOOP_DEV_P1 = /dev/loop0p1
@@ -38,6 +35,7 @@ all:
 clean:
        make -C ../src/ clean
        -rm -f $(IMG_NAME)
+       -rm -rf objs
 
 # ディスクイメージの作成
 .PHONY: image
@@ -49,16 +47,7 @@ image: $(IMG_NAME)
 #******************************************************************************#
 $(IMG_NAME): all
        sync
-       dd if=/dev/zero of=$@ count=10080 conv=fsync
-       dd if=$(BOOTER_IPL) of=$@ conv=notrunc,fsync
-       dd if=$(PTABLE) of=$@ ibs=1 obs=1 seek=446 conv=notrunc,fsync
-       sudo losetup $(LOOP_DEV) $@
-       -sudo partx -a $(LOOP_DEV)
-       -sudo dd if=$(BOOTER_MAIN) of=$(LOOP_DEV_P1) conv=fsync
-       -sudo dd if=$(KERNEL) of=$(LOOP_DEV_P2) conv=fsync
+       tools/makedisk -o $@ -i $(BOOTER_IPL) -b $(BOOTER_MAIN) -k $(KERNEL)
        sync
-       -sudo partx -d $(LOOP_DEV)
-       sudo losetup -d $(LOOP_DEV)
-
 
 #******************************************************************************#
diff --git a/build/ptable.bin b/build/ptable.bin
deleted file mode 100644 (file)
index f009ca0..0000000
Binary files a/build/ptable.bin and /dev/null differ
index 86c2c97..703be49 100644 (file)
@@ -1,13 +1,14 @@
 #******************************************************************************#
 #* src/Makefile                                                               *#
-#*                                                                 2016/12/13 *#
-#* Copyright (C) 2016 Mochi.                                                  *#
+#*                                                                 2017/07/11 *#
+#* Copyright (C) 2016-2017 Mochi.                                             *#
 #******************************************************************************#
 #******************************************************************************#
 #* マクロ設定                                                                 *#
 #******************************************************************************#
 # サブディレクトリ
-SUB_DIRS = libraries \
+SUB_DIRS = tools     \
+           libraries \
            booter    \
            kernel
 
diff --git a/src/booter/Debug/DebugInit.c b/src/booter/Debug/DebugInit.c
new file mode 100644 (file)
index 0000000..4a2f84d
--- /dev/null
@@ -0,0 +1,51 @@
+/******************************************************************************/
+/* src/booter/Debug/DebugInit.c                                               */
+/*                                                                 2017/06/26 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+
+/* 内部モジュールヘッダ */
+#include "DebugLog.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                    \
+    DebugLogOutput( CMN_MODULE_DEBUG_INIT,  \
+                    __LINE__,               \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       デバッグ制御初期化
+ * @details     デバッグ制御内サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void DebugInit( void )
+{
+    /* ログ管理サブモジュール初期化 */
+    DebugLogInit();
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/Debug/DebugLog.c b/src/booter/Debug/DebugLog.c
new file mode 100644 (file)
index 0000000..a02da56
--- /dev/null
@@ -0,0 +1,1180 @@
+/******************************************************************************/
+/* src/booter/Debug/DebugLog.c                                                */
+/*                                                                 2017/07/04 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <hardware/Vga/Vga.h>
+
+/* 内部モジュールヘッダ */
+#include "DebugLog.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* 長さ定義 */
+#define LOG_LENGTH_ID      (  8 )   /** 識別子文字数 */
+#define LOG_LENGTH_LINENUM (  4 )   /** 行番号文字数 */
+
+/** カーソル位置アドレス計算 */
+#define LOG_CURSOR_ADDR( __ROW, __COLUMN )                  \
+    ( ( uint8_t * ) ( VGA_M3_VRAM_ADDR +                    \
+                      ( __ROW ) * VGA_M3_COLUMN * 2 +       \
+                      ( __COLUMN ) * 2                ) )
+
+/** 文字色取得マクロ */
+#define LOG_ATTR_FG( __BASE )           ( __BASE & 0x0F )
+
+/** 背景色取得マクロ */
+#define LOG_ATTR_BG( __BASE )           ( __BASE & 0xF0 )
+
+/** 文字色変更マクロ */
+#define LOG_ATTR_FG_CHG( __BASE, __FG ) ( LOG_ATTR_BG( __BASE ) | ( __FG ) )
+
+/** 背景色変更マクロ */
+#define LOG_ATTR_BG_CHG( __BASE, __BG ) ( LOG_ATTR_FG( __BASE ) | ( __BG ) )
+
+/* 変換指定子フラグ */
+#define LOG_FLAG_LEFT      ( 0x01 ) /* 左寄せ       */
+#define LOG_FLAG_SIGN      ( 0x02 ) /* 符号表示     */
+#define LOG_FLAG_SPACE     ( 0x04 ) /* 正数符号空白 */
+#define LOG_FLAG_ALTERNATE ( 0x08 ) /* 代替形式     */
+#define LOG_FLAG_ZERO      ( 0x10 ) /* 0埋め        */
+#define LOG_FLAG_UPPERCASE ( 0x20 ) /* 大文字       */
+#define LOG_FLAG_UNSIGNED  ( 0x40 ) /* 符号無       */
+
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                \
+    DebugLogOutput( CMN_MODULE_DBG_LOG, \
+                    __LINE__,           \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/** 識別子変換テーブル型 */
+typedef struct {
+    uint32_t moduleId;                  /**< モジュール・サブモジュール識別子 */
+    char     str[ LOG_LENGTH_ID + 1 ];  /**< 識別文字列                       */
+} logIdTrans_t;
+
+/** ログ管理テーブル型 */
+typedef struct {
+    uint32_t row;       /**< カーソル行 */
+    uint32_t column;    /**< カーソル列 */
+    uint8_t  attr;      /**< 文字属性   */
+} logTbl_t;
+
+
+/******************************************************************************/
+/* ローカル変数定義                                                           */
+/******************************************************************************/
+#ifdef DEBUG_LOG_ENABLE
+/** 識別子変換テーブル */
+const static logIdTrans_t gIdTransTbl[ CMN_MODULE_NUM + 1 ] = {
+    { CMN_MODULE_INIT_INIT,      "INI-INIT" },    /* 初期化制御(初期化)     */
+    { CMN_MODULE_INTMNG_INIT,    "INT-INIT" },    /* 割込管理(初期化)       */
+    { CMN_MODULE_INTMNG_PIC,     "INT-PIC " },    /* 割込管理(PIC管理)      */
+    { CMN_MODULE_INTMNG_IDT,     "INT-IDT " },    /* 割込管理(IDT管理)      */
+    { CMN_MODULE_INTMNG_HDL,     "INT-HDL " },    /* 割込管理(ハンドラ管理) */
+    { CMN_MODULE_DRIVER_INIT,    "DRV-INIT" },    /* ドライバ(初期化)       */
+    { CMN_MODULE_DRIVER_A20,     "DRV-A20 " },    /* ドライバ(A20)          */
+    { CMN_MODULE_DRIVER_ATA,     "DRV-ATA " },    /* ドライバ(ATA)          */
+    { CMN_MODULE_LOADMNG_INIT,   "LDM-INIT" },    /* 読込管理               */
+    { CMN_MODULE_LOADMNG_KERNEL, "LDM-KRNL" },    /* 読込管理(カーネル)     */
+    { CMN_MODULE_DEBUG_INIT,     "DBG-INIT" },    /* デバッグ制御(初期化)   */
+    { CMN_MODULE_DEBUG_LOG,      "DBG-LOG " },    /* デバッグ制御(ログ管理) */
+    { 0,                         "UNKNOWN " }  }; /* 終端                   */
+#endif
+
+/** 数字変換表 */
+static char gNumTransTbl[ 2 ][ 17 ] = { "0123456789abcdef",
+                                        "0123456789ABCDEF"  };
+
+/** ログ管理テーブル */
+static logTbl_t gLogTbl;
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+#ifdef DEBUG_LOG_ENABLE
+
+/* 数値取得 */
+static CmnRet_t LogGetNum( char     *pStr,
+                           uint32_t *pValue,
+                           uint32_t *pLength );
+
+/* 書式付き文字列出力(可変長引数型) */
+static void LogOutput( char *pFormat,
+                       ...            );
+
+/* 書式付き文字列出力(可変長引数リスト型) */
+static void LogOutputByVaList( char     *pFormat,
+                               va_list  vaList    );
+
+/* 一文字出力 */
+static void LogOutputChar( char c );
+
+/* 整数出力 */
+static void LogOutputNumber( uint32_t value,
+                             uint32_t base,
+                             uint32_t flags,
+                             int32_t  width  );
+
+/* 文字列出力 */
+static void LogOutputString( char *pStr );
+
+/* ESCコード処理 */
+static uint32_t LogProcEscape( char *pStr );
+
+/* 文字属性エスケープシーケンス処理 */
+static void LogProcEscapeAttr( uint32_t funcNo );
+
+/* 変換指定子処理 */
+static uint32_t LogProcFormat( char    *pFormat,
+                               va_list *pVaList  );
+
+#endif
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       ログ管理初期化
+ * @details     ログ管理サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void DebugLogInit( void )
+{
+    /* ログ管理テーブル初期化 */
+    memset( &gLogTbl, 0, sizeof ( logTbl_t ) );
+    
+    /* 文字属性設定 */
+    gLogTbl.attr = VGA_M3_ATTR_FG_WHITE  |  /* 白色文字属性 */
+                   VGA_M3_ATTR_FG_BRIGHT |  /* 明色文字属性 */
+                   VGA_M3_ATTR_BG_BLACK;    /* 黒色背景属性 */
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       トレースログ出力
+ * @details     デバッグトレースログオプションが有効の時、画面にトレースログ出
+ *              力を行う。
+ * 
+ * @param[in]   moduleId モジュール・サブモジュール識別子
+ *                  - CMN_MODULE_INIT_INIT     初期化制御(初期化)
+ *                  - CMN_MODULE_MEMMNG_INIT   メモリ管理(初期化)
+ *                  - CMN_MODULE_MEMMNG_GDT    メモリ管理(GDT管理)
+ *                  - CMN_MODULE_MEMMNG_AREA   メモリ管理(メモリ領域管理)
+ *                  - CMN_MODULE_MEMMNG_PAGE   メモリ管理(ページ管理)
+ *                  - CMN_MODULE_MEMMNG_CTRL   メモリ管理(メモリ制御)
+ *                  - CMN_MODULE_INTMNG_INIT   割込管理(初期化)
+ *                  - CMN_MODULE_INTMNG_PIC    割込管理(PIC管理)
+ *                  - CMN_MODULE_INTMNG_IDT    割込管理(IDT管理)
+ *                  - CMN_MODULE_INTMNG_HDL    割込管理(ハンドラ管理)
+ *                  - CMN_MODULE_TIMERMNG_INIT タイマ管理(初期化)
+ *                  - CMN_MODULE_TIMERMNG_PIT  タイマ管理(PIT管理)
+ *                  - CMN_MODULE_PROCMNG_INIT  プロセス管理(初期化)
+ *                  - CMN_MODULE_PROCMNG_TSS   プロセス管理(TSS管理)
+ *                  - CMN_MODULE_PROCMNG_SCHED プロセス管理(スケジューラ)
+ *                  - CMN_MODULE_PROCMNG_TASK  プロセス管理(タスク管理)
+ *                  - CMN_MODULE_DEBUG_INIT    デバッグ制御(初期化)
+ *                  - CMN_MODULE_DEBUG_LOG     デバッグ制御(ログ管理)
+ * @param[in]   lineNum  行番号
+ * @param[in]   *pFormat トレースログ
+ * 
+ * @note        デバッグトレースログオプションの有効化は、コンパイルオプション
+ *              にて「DEBUG_LOG_ENABLE」マクロを定義する事で行う。
+ */
+/******************************************************************************/
+void DebugLogOutput( uint32_t moduleId,
+                     uint32_t lineNum,
+                     char     *pFormat,
+                     ...                )
+{
+#ifdef DEBUG_LOG_ENABLE
+    va_list  vaList;    /* 可変長引数リスト         */
+    uint32_t row;       /* カーソル行               */
+    uint32_t column;    /* カーソル列               */
+    uint32_t moduleIdx; /* 変換テーブルインデックス */
+    
+    /* 可変長引数リスト設定 */
+    va_start( vaList, pFormat );
+    
+    /* カーソル列初期化 */
+    gLogTbl.column = 0;
+    
+    /* カーソル行範囲判定 */
+    if ( gLogTbl.row >= VGA_M3_ROW ) {
+        /* 上限越え */
+        
+        /* カーソル行設定 */
+        gLogTbl.row = VGA_M3_ROW - 1;
+        
+        /* 画面スクロール */
+        for ( row = 0; row < ( VGA_M3_ROW - 1 ); row++ ) {
+            /* 一行コピー */
+            memcpy( LOG_CURSOR_ADDR( row, 0 ),
+                    LOG_CURSOR_ADDR( row + 1, 0 ),
+                    VGA_M3_COLUMN * 2 );
+        }
+        
+        /* 最下行初期化 */
+        for ( column = 0; column < VGA_M3_COLUMN; column++ ) {
+            /* 一文字設定 */
+            LOG_CURSOR_ADDR( row, column )[ 0 ] = ' ';
+            LOG_CURSOR_ADDR( row, column )[ 1 ] =
+                VGA_M3_ATTR_FG_WHITE  |     /* 白色文字属性 */
+                VGA_M3_ATTR_FG_BRIGHT |     /* 明色文字属性 */
+                VGA_M3_ATTR_BG_BLACK;       /* 黒色背景属性 */
+        }
+    }
+    
+    /* モジュール・サブモジュール識別子変換 */
+    for ( moduleIdx = 0; moduleIdx < CMN_MODULE_NUM; moduleIdx++ ) {
+        /* 識別子変換テーブル一致判定 */
+        if ( gIdTransTbl[ moduleIdx ].moduleId == moduleId ) {
+            /* 一致 */
+            break;
+        }
+    }
+    
+    /* モジュール・サブモジュール識別子、行番号出力 */
+    LogOutput( "\033[32m%s:%04u \033[0m",
+               gIdTransTbl[ moduleIdx ].str,
+               lineNum % 10000               );
+    
+    /* トレースログ出力 */
+    LogOutputByVaList( pFormat, vaList );
+    
+    /* カーソル行更新 */
+    gLogTbl.row++;
+    
+    /* 可変長引数リスト解放 */
+    va_end( vaList );
+    
+#endif
+    return;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       数値取得
+ * @details     数字文字列から数値を取得する。
+ * 
+ * @param[in]   *pStr    文字列
+ * @param[out]  *pVaule  数値
+ * @param[out]  *pLength 数字文字列長
+ * 
+ * @retval      CMN_SUCCESS 正常終了
+ * @retval      CMN_FAILURE 異常終了(数字文字列無し)
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static CmnRet_t LogGetNum( char     *pStr,
+                           uint32_t *pValue,
+                           uint32_t *pLength )
+{
+    /* 初期化 */
+    *pValue  = 0;
+    *pLength = 0;
+    
+    /* 一文字毎に繰り返す */
+    while ( pStr[ *pLength ] != '\0' ) {
+        /* 数値判別 */
+        if ( ( '0' <= pStr[ *pLength ] ) && ( pStr[ *pLength ] <= '9' ) ) {
+            /* 数値 */
+            *pValue = *pValue * 10 + pStr[ *pLength ] - '0';
+            
+        } else {
+            /* 数値以外 */
+            
+            break;
+        }
+        
+        /* 文字列長更新 */
+        ( *pLength )++;
+    }
+    
+    /* 文字列長判定 */
+    if ( *pLength == 0 ) {
+        /* 数値無 */
+        
+        return CMN_FAILURE;
+    }
+    
+    return CMN_SUCCESS;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       書式付き文字列出力(可変長引数型)
+ * @details     画面に可変長引数型書式付き文字列を出力する。
+ * 
+ * @param[in]   *pFormat 書式付き文字列
+ * @param[in]   ...      可変長引数
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static void LogOutput( char *pFormat,
+                       ...            )
+{
+    va_list vaList; /* 可変長引数リスト */
+    
+    /* 可変長引数リスト設定 */
+    va_start( vaList, pFormat );
+    
+    /* 書式付き文字列出力 */
+    LogOutputByVaList( pFormat, vaList );
+    
+    /* 可変長引数リスト解放 */
+    va_end( vaList );
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       書式付き文字列出力(可変長引数リスト型)
+ * @details     画面に可変長引数リスト型書式付き文字列を出力する。
+ * 
+ * @param[in]   *pFormat 書式付き文字列
+ * @param[in]   vaList   可変長引数リスト
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static void LogOutputByVaList( char     *pFormat,
+                               va_list  vaList    )
+{
+    uint32_t idx;   /* インデックス */
+    
+    /* 初期化 */
+    idx = 0;
+    
+    /* 一文字毎に繰り返し */
+    while ( pFormat[ idx ] != '\0' ) {
+        /* 文字判定 */
+        switch ( pFormat[ idx ] ) {
+            case '%':
+                /* 変換指定子 */
+                
+                /* インデックス更新 */
+                idx++;
+                
+                /* 変換指定処理 */
+                idx += LogProcFormat( &pFormat[ idx ], &vaList );
+                
+                break;
+                
+            case '\033':
+                /* ESCコード */
+                
+                /* インデックス更新 */
+                idx++;
+                
+                /* ESCコード処理 */
+                idx += LogProcEscape( &pFormat[ idx ] );
+                
+                break;
+                
+            default:
+                /* その他 */
+                
+                /* 一文字出力 */
+                LogOutputChar( pFormat[ idx ] );
+                
+                /* インデックス更新 */
+                idx++;
+                
+                break;
+        }
+    }
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       一文字出力
+ * @details     画面に一文字出力する。
+ * 
+ * @param[in]   c 文字コード
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static void LogOutputChar( char c )
+{
+    uint8_t *pCursor;   /* カーソル */
+    
+    /* カーソル列チェック */
+    if ( gLogTbl.column >= VGA_M3_COLUMN ) {
+        /* 行数超 */
+        
+        return;
+    }
+    
+    /* カーソル設定 */
+    pCursor = LOG_CURSOR_ADDR( gLogTbl.row, gLogTbl.column );
+    
+    /* 画面出力 */
+    pCursor[ 0 ] = ( uint8_t ) c;   /* 文字コード */
+    pCursor[ 1 ] = gLogTbl.attr;    /* 文字属性   */
+    
+    /* カーソル更新 */
+    gLogTbl.column++;
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       整数出力
+ * @details     整数を画面に出力する。
+ * 
+ * @param[in]   value 数値
+ * @param[in]   base  進数
+ *                  - 8  8進数
+ *                  - 10 10進数
+ *                  - 16 16進数
+ * @param[in]   flags フラグ
+ *                  - LOG_FLAG_LEFT      左寄せ
+ *                  - LOG_FLAG_SIGN      符号表示
+ *                  - LOG_FLAG_SPACE     正数符号空白
+ *                  - LOG_FLAG_ALTERNATE 代替形式
+ *                  - LOG_FLAG_ZERO      0埋め
+ *                  - LOG_FLAG_UNSIGNED  符号無
+ * @param[in]   width 最小フィールド幅
+ *                  - 0~80
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static void LogOutputNumber( uint32_t value,
+                             uint32_t base,
+                             uint32_t flags,
+                             int32_t  width  )
+{
+    char     buffer[ VGA_M3_COLUMN ];   /* 出力バッファ     */
+    char     *pTrans;                   /* 数字変換表       */
+    int32_t  length;                    /* バッファ文字列長 */
+    uint32_t tmp;                       /* 一時変数         */
+    uint32_t idx;                       /* インデックス     */
+    
+    /* 初期化 */
+    memset( buffer, '0', sizeof ( buffer ) );
+    length = 0;
+    tmp    = value;
+    
+    /* 最小フィールド幅範囲チェック */
+    if ( ( width < 0 ) && ( VGA_M3_COLUMN <= width ) ) {
+        /* 0未満、LOG_LENGTH_COLUMN超過 */
+        
+        /* 最小フィールド幅初期化 */
+        width = 0;
+    }
+    
+    /* 左寄せフラグ判定 */
+    if ( ( flags & LOG_FLAG_LEFT ) != 0 ) {
+        /* 左寄せフラグ有 */
+        
+        /* 0フラグ無効化 */
+        flags = flags & ~LOG_FLAG_ZERO;
+    }
+    
+    /* 符号無フラグ判定 */
+    if ( ( flags & LOG_FLAG_UNSIGNED ) == 0 ) {
+        /* 符号無フラグ無 */
+        
+        /* 負数判定 */
+        if ( ( ( int32_t ) tmp ) < 0 ) {
+            /* 負数 */
+            
+            /* 正数化 */
+            tmp = ( uint32_t ) ( ( ( int32_t ) tmp ) * -1 );
+        }
+        
+    } else {
+        /* 符号無フラグ有 */
+        
+        /* フラグ無効化 */
+        flags &= ~LOG_FLAG_SIGN;    /* 符号表示     */
+        flags &= ~LOG_FLAG_SPACE;   /* 正数符号空白 */
+    }
+    
+    /* 大文字フラグ判定 */
+    if ( ( flags & LOG_FLAG_UPPERCASE ) == 0 ) {
+        /* 大文字フラグ無 */
+        
+        /* 数字変換表設定 */
+        pTrans = gNumTransTbl[ 0 ];
+        
+    } else {
+        /* 大文字フラグ有 */
+        
+        /* 数字変換表設定 */
+        pTrans = gNumTransTbl[ 1 ];
+    }
+    
+    /* 代替形式フラグ判定 */
+    if ( ( flags & LOG_FLAG_ALTERNATE ) != 0 ) {
+        /* 代替表示フラグ有 */
+        
+        /* 進数判定 */
+        if ( base == 8 ) {
+            /* 8進数 */
+            
+            /* 最小フィールド幅から代替形式出力分減算 */
+            width -= 1;
+            
+        } else if ( base == 16 ) {
+            /* 16進数 */
+            
+            /* 最小フィールド幅から代替形式出力分減算 */
+            width -= 2;
+        }
+    }
+    
+    /* 符号表示フラグ、正数符号空白フラグ判定 */
+    if ( ( ( flags & LOG_FLAG_SIGN  ) != 0 ) ||
+         ( ( flags & LOG_FLAG_SPACE ) != 0 )    ) {
+        /* 符号表示フラグ有、または、正数符号空白フラグ有 */
+        
+        /* 最小フィールド幅から符号出力分減算 */
+        width -= 1;
+    }
+    
+    /* 一桁毎に繰り返し */
+    do {
+        /* 一桁文字列変換 */
+        buffer[ length++ ] = pTrans[ tmp % base ];
+        
+        /* 値更新 */
+        tmp /= base;
+        
+    } while ( tmp != 0 );
+    
+    /* 0埋めフラグ、最小フィールド幅判定 */
+    if ( ( ( flags & LOG_FLAG_ZERO ) != 0      ) &&
+         ( width                     >  length )    ) {
+        /* 0埋めフラグ有、かつ、最小フィールド幅未満 */
+        
+        /* 最小フィールド幅合わせ */
+        length = width;
+    }
+    
+    /* 代替形式フラグ判定 */
+    if ( ( flags & LOG_FLAG_ALTERNATE ) != 0 ) {
+        /* 代替表示フラグ有 */
+        
+        /* 進数判定 */
+        if ( base == 8 ) {
+            /* 8進数 */
+            
+            /* 0をバッファ出力 */
+            buffer[ length++ ] = '0';
+            
+        } else if ( base == 16 ) {
+            /* 16進数 */
+            
+            /* 0xをバッファ出力 */
+            buffer[ length++ ] = 'x';
+            buffer[ length++ ] = '0';
+        }
+    }
+    
+    /* 符号表示フラグ・正数判定 */
+    if ( ( ( flags & LOG_FLAG_SIGN ) != 0 ) &&
+         ( ( int32_t ) value         >= 0 )    ) {
+        /* 符号表示フラグ有、かつ、正数 */
+        buffer[ length++ ] = '+';
+    }
+    
+    /* 正数符号空白フラグ・正数判定 */
+    if ( ( ( flags & LOG_FLAG_SPACE ) != 0 ) &&
+         ( ( int32_t ) value          >= 0 )    ) {
+        /* 正数符号空白フラグ有、かつ、正数 */
+        buffer[ length++ ] = ' ';
+    }
+    
+    /* 符号表示フラグ・正数符号空白フラグ・負数判定 */
+    if ( ( ( ( flags & LOG_FLAG_SIGN  ) != 0 ) ||
+           ( ( flags & LOG_FLAG_SPACE ) != 0 )    ) &&
+         ( ( int32_t ) value < 0                  )    ) {
+        /* 符号表示または正数符号空白フラグ有、かつ、負数 */
+        buffer[ length++ ] = '-';
+    }
+    
+    /* 左寄せフラグ、最小フィールド幅判定 */
+    if ( ( ( flags & LOG_FLAG_LEFT ) == 0      ) &&
+         ( width                     >  length )    ) {
+        /* 左寄せフラグ無、かつ、最小フィールド幅未満 */
+        
+        /* 空白挿入 */
+        for ( idx = 0; idx < ( uint32_t ) ( width - length ); idx++ ) {
+            /* 一文字出力 */
+            LogOutputChar( ' ' );
+        }
+    }
+    
+    /* バッファ出力 */
+    for ( idx = 0; idx < ( uint32_t ) length; idx++ ) {
+        /* 一文字出力 */
+        LogOutputChar( buffer[ ( uint32_t ) length - idx - 1 ] );
+    }
+    
+    /* 左寄せフラグ判定 */
+    if ( ( ( flags & LOG_FLAG_LEFT ) != 0      ) &&
+         ( width                     >  length )    ) {
+        /* 左寄せフラグ有、かつ、最小フィールド幅未満 */
+        
+        /* 空白挿入 */
+        for ( idx = 0; idx < ( uint32_t ) ( width - length ); idx++ ) {
+            /* 一文字出力 */
+            LogOutputChar( ' ' );
+        }
+    }
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       文字列出力
+ * @details     文字列を画面に出力する。
+ * 
+ * @param[in]   pStr 文字列
+ * 
+ * @note        「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ */
+/******************************************************************************/
+static void LogOutputString( char *pStr )
+{
+    uint32_t idx;   /* インデックス */
+    
+    /* 初期化 */
+    idx = 0;
+    
+    /* 一文字毎に繰り返し */
+    while ( pStr[ idx ] != '\0' ) {
+        /* 文字判定 */
+        switch ( pStr[ idx ] ) {
+            case '\033':
+                /* ESCコード */
+                
+                /* インデックス更新 */
+                idx++;
+                
+                /* ESCコード処理 */
+                idx += LogProcEscape( &pStr[ idx ] );
+                
+                break;
+                
+            default:
+                /* 他 */
+                
+                /* 一文字出力 */
+                LogOutputChar( pStr[ idx ] );
+                
+                /* インデックス更新 */
+                idx++;
+                
+                break;
+        }
+    }
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       ESCコード処理
+ * @details     ESCコードを処理する。
+ * 
+ * @param[in]   *pStr エスケープシーケンス
+ * 
+ * @return      エスケープシーケンス文字数
+ * 
+ * @note        - 「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ *              - 画面制御エスケープシーケンスには対応しない。
+ */
+/******************************************************************************/
+static uint32_t LogProcEscape( char *pStr )
+{
+    CmnRet_t ret;       /* 関数戻り値   */
+    uint32_t idx;       /* インデックス */
+    uint32_t value;     /* 数値         */
+    uint32_t length;    /* 文字列長     */
+    
+    /* 初期化 */
+    idx    = 1;
+    value  = 0;
+    length = 0;
+    
+    /* エスケープシーケンスチェック */
+    if ( pStr[ 0 ] != '['  ) {
+        /* エスケープシーケンスでない */
+        
+        return 0;
+    }
+    
+    /* 数値取得 */
+    ret = LogGetNum( &pStr[ idx ], &value, &length );
+    
+    /* 取得結果判定 */
+    if ( ret == CMN_SUCCESS ) {
+        /* 成功 */
+        
+        /* インデックス更新 */
+        idx += length;
+    }
+    
+    /* エスケープシーケンス種別判定 */
+    switch ( pStr[ idx ] ) {
+        case 'm':
+            /* 文字属性 */
+            
+            /* 文字属性エスケープシーケンス処理 */
+            LogProcEscapeAttr( value );
+            
+            /* 文字列長設定 */
+            length = idx + 1;
+            
+            break;
+            
+        default:
+            /* 他 */
+            
+            /* 文字列長設定 */
+            length = idx;
+            
+            break;
+    }
+    
+    return length;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       文字属性エスケープシーケンス処理
+ * @details     文字属性のエスケープシーケンスを処理する。
+ * 
+ * @param[in]   funcNo 機能番号
+ *                  - 0  属性初期化
+ *                  - 1  文字強調
+ *                  - 4  下線
+ *                  - 7  反転
+ *                  - 30 黒色文字
+ *                  - 31 赤色文字
+ *                  - 32 緑色文字
+ *                  - 33 黄色文字
+ *                  - 34 青色文字
+ *                  - 35 紫色文字
+ *                  - 36 水色文字
+ *                  - 37 白色文字
+ *                  - 39 標準色文字
+ *                  - 40 黒色背景
+ *                  - 41 赤色背景
+ *                  - 42 緑色背景
+ *                  - 43 黄色背景
+ *                  - 44 青色背景
+ *                  - 45 紫色背景
+ *                  - 46 水色背景
+ *                  - 47 白色背景
+ *                  - 49 標準色背景
+ * 
+ * @note        - 「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ *              - 文字強調、下線は対応しない。
+ */
+/******************************************************************************/
+static void LogProcEscapeAttr( uint32_t funcNo )
+{
+    uint8_t attr;   /* 文字属性 */
+    
+    /* 機能番号判定 */
+    switch ( funcNo ) {
+        case 0:
+            /* 属性初期化 */
+            
+            gLogTbl.attr = VGA_M3_ATTR_FG_WHITE  |  /* 白色文字属性 */
+                           VGA_M3_ATTR_FG_BRIGHT |  /* 明色文字属性 */
+                           VGA_M3_ATTR_BG_BLACK;    /* 黒色背景属性 */
+            
+            break;
+            
+        case 7:
+            /* 反転 */
+            
+            /* 反転 */
+            attr  = ( LOG_ATTR_BG( gLogTbl.attr ) >> 4 ) |
+                    VGA_M3_ATTR_FG_BRIGHT;
+            attr &= ( LOG_ATTR_FG( gLogTbl.attr ) << 4 ) & ~VGA_M3_ATTR_BLINK;
+            
+            /* 設定 */
+            gLogTbl.attr = attr;
+            
+            break;
+            
+        case 30:
+            /* 黒色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_BLACK | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 31:
+            /* 赤色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_RED | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 32:
+            /* 緑色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_GREEN | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 33:
+            /* 黄色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_BROWN | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 34:
+            /* 青色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_BLUE | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 35:
+            /* 紫色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_PURPLE | 
+                                     VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 36:
+            /* 水色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_CYAN | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 37:
+            /* 白色文字 *//* FALL THROUGH */
+        case 39:
+            /* 標準色文字 */
+            gLogTbl.attr =
+                LOG_ATTR_FG_CHG( gLogTbl.attr,
+                                 VGA_M3_ATTR_FG_WHITE | VGA_M3_ATTR_FG_BRIGHT );
+            break;
+            
+        case 40:
+            /* 黒色背景 *//* FALL THROUGH */
+        case 49:
+            /* 標準色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr,
+                                            VGA_M3_ATTR_BG_BLACK );
+            break;
+            
+        case 41:
+            /* 赤色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr, VGA_M3_ATTR_BG_RED );
+            break;
+            
+        case 42:
+            /* 緑色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr, VGA_M3_ATTR_BG_RED );
+            break;
+            
+        case 43:
+            /* 黄色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr,
+                                            VGA_M3_ATTR_BG_BROWN );
+            break;
+            
+        case 44:
+            /* 青色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr, VGA_M3_ATTR_BG_BLUE );
+            break;
+            
+        case 45:
+            /* 紫色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr,
+                                            VGA_M3_ATTR_BG_PURPLE );
+            break;
+            
+        case 46:
+            /* 水色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr, VGA_M3_ATTR_BG_CYAN );
+            break;
+            
+        case 47:
+            /* 白色背景 */
+            gLogTbl.attr = LOG_ATTR_BG_CHG( gLogTbl.attr,
+                                            VGA_M3_ATTR_BG_WHITE );
+            break;
+            
+        default:
+            /* 他 */
+            break;
+    }
+    
+    return;
+}
+#endif
+
+
+#ifdef DEBUG_LOG_ENABLE
+/******************************************************************************/
+/**
+ * @brief       変換指定子処理
+ * @details     変換指定子を処理する。
+ * 
+ * @param[in]   *pFormat 変換指定子
+ * @param[in]   vaList   可変長引数リスト
+ * 
+ * @note        - 「DEBUG_LOG_ENABLE」マクロが定義されている場合に有効となる。
+ *              - 精度、長さ修飾子は未対応。
+ */
+/******************************************************************************/
+static uint32_t LogProcFormat( char    *pFormat,
+                               va_list *pVaList  )
+{
+    uint32_t idx;       /* インデックス     */
+    uint32_t width;     /* 最小フィールド幅 */
+    uint32_t flags;     /* フラグ           */
+    uint32_t length;    /* 文字列長         */
+    CmnRet_t ret;       /* 関数戻り値       */
+    
+    /* 初期化 */
+    idx    = 0;
+    flags  = 0;
+    width  = 0;
+    length = 0;
+    
+    /* フラグ判定 */
+    while ( 1 ) {
+        switch ( pFormat[ idx ] ) {
+            case '-':
+                /* 左寄せ */
+                idx++;                      /* インデックス更新 */
+                flags |= LOG_FLAG_LEFT;     /* フラグ設定       */
+                continue;
+                
+            case '+':
+                /* 符号表示 */
+                idx++;                      /* インデックス更新 */
+                flags |= LOG_FLAG_SIGN;     /* フラグ設定       */
+                continue;
+                
+            case ' ':
+                /* 正数符号空白 */
+                idx++;                      /* インデックス更新 */
+                flags |= LOG_FLAG_SPACE;    /* フラグ設定       */
+                continue;
+                
+            case '#':
+                /* 代替形式 */
+                idx++;                      /* インデックス更新 */
+                flags |= LOG_FLAG_ALTERNATE;/* フラグ設定       */
+                continue;
+                
+            case '0':
+                /* 0埋め */
+                idx++;                      /* インデックス更新 */
+                flags |= LOG_FLAG_ZERO;     /* フラグ設定       */
+                continue;
+                
+            case '\0':
+                /* 終端 */
+                return 0;
+                
+            default:
+                /* 他 */
+                break;
+        }
+        break;
+    }
+    
+    /* 最小フィールド幅取得 */
+    ret = LogGetNum( &pFormat[ idx ], &width, &length );
+    
+    /* 取得結果判定 */
+    if ( ret == CMN_SUCCESS ) {
+        /* 最小フィールド幅有り */
+        
+        /* インデックス更新 */
+        idx += length;
+    }
+    
+    /* 変換指定子判定 */
+    switch ( pFormat[ idx ] ) {
+        case 'u':
+            /* 10進符号無整数 *//* FALL THROUGH */
+            
+            /* フラグ設定 */
+            flags |= LOG_FLAG_UNSIGNED;     /* 符号無 */
+            
+        case 'd':
+            /* 10進符号付整数 *//* FALL THROUGH */
+        case 'i':
+            /* 10進符号付整数 */
+            
+            /* 10進整数出力 */
+            LogOutputNumber( va_arg( *pVaList, uint32_t ), 10, flags, width );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case 'o':
+            /* 8進符号無整数 */
+            
+            /* フラグ設定 */
+            flags |= LOG_FLAG_UNSIGNED;     /* 符号無 */
+            
+            /* 8進整数出力 */
+            LogOutputNumber( va_arg( *pVaList, uint32_t ), 8, flags, width );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case 'X':
+            /* 16進符号無整数(大文字) *//* FALL THROUGH */
+            
+            /* フラグ設定 */
+            flags |= LOG_FLAG_UNSIGNED;     /* 符号無 */
+            flags |= LOG_FLAG_UPPERCASE;    /* 大文字 */
+            
+        case 'x':
+            /* 16進符号無整数(小文字) */
+            
+            /* フラグ設定 */
+            flags |= LOG_FLAG_UNSIGNED;     /* 符号無 */
+            
+            /* 16進整数出力 */
+            LogOutputNumber( va_arg( *pVaList, uint32_t ), 16, flags, width );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case 'c':
+            /* 文字 */
+            
+            /* 一文字出力 */
+            LogOutputChar( ( char ) va_arg( *pVaList, int ) );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case 's':
+            /* 文字列 */
+            
+            /* 文字列出力 */
+            LogOutputString( va_arg( *pVaList, char * ) );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case 'p':
+            /* ポインタ */
+            
+            /* フラグ設定 */
+            flags |= LOG_FLAG_ALTERNATE;    /* 代替表示 */
+            flags |= LOG_FLAG_UNSIGNED;     /* 符号無   */
+            
+            /* 16進整数出力 */
+            LogOutputNumber( va_arg( *pVaList, uint32_t ), 16, flags, width );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        case '%':
+            /* % */
+            
+            /* 一文字出力 */
+            LogOutputChar( '%' );
+            
+            /* 文字列長設定 */
+            length = 1;
+            
+            break;
+            
+        default:
+            /* 他 */
+            
+            /* 文字列長設定 */
+            length = 0;
+            
+            break;
+    }
+    
+    return idx + length;
+}
+#endif
+
+
+/******************************************************************************/
diff --git a/src/booter/Debug/DebugLog.h b/src/booter/Debug/DebugLog.h
new file mode 100644 (file)
index 0000000..f60770f
--- /dev/null
@@ -0,0 +1,16 @@
+/******************************************************************************/
+/* src/booter/Debug/DebugLog.h                                                */
+/*                                                                 2017/06/26 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef DEBUG_LOG_H
+#define DEBUG_LOG_H
+/******************************************************************************/
+/* グローバル関数プロトタイプ宣言                                             */
+/******************************************************************************/
+/* ログ管理サブモジュール初期化 */
+extern void DebugLogInit( void );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/Driver/DriverA20.c b/src/booter/Driver/DriverA20.c
new file mode 100644 (file)
index 0000000..3fbe19e
--- /dev/null
@@ -0,0 +1,252 @@
+/******************************************************************************/
+/* src/booter/Driver/DriverA20.c                                              */
+/*                                                                 2017/07/10 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <hardware/IA32/IA32.h>
+#include <hardware/IA32/IA32Instruction.h>
+#include <MLib/Basic/MLibBasic.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                   \
+    DebugLogOutput( CMN_MODULE_DRIVER_A20, \
+                    __LINE__,              \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+/* A20ライン有効化チェック */
+static CmnRet_t A20CheckEnable( void );
+
+/* A20ライン有効化(System Port A) */
+static void A20EnableBySysPortA( void );
+
+/* A20ライン有効化(Keyboard Controller) */
+static void A20EnableByKbc( void );
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       A20ライン有効化
+ * @details     A20ラインを有効化し、1MiB以上のメモリをアクセス可能にする。
+ * 
+ * @retval      CMN_SUCCESS 正常終了
+ * @retval      CMN_FAILURE 異常終了
+ */
+/******************************************************************************/
+CmnRet_t DriverA20Enable( void )
+{
+    CmnRet_t ret;   /* 関数戻り値 */
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* A20ライン有効化判定 */
+    ret = A20CheckEnable();
+    
+    /* 有効化判定 */
+    if ( ret == CMN_SUCCESS ) {
+        /* 有効 */
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ );
+        
+        return CMN_SUCCESS;
+    }
+    
+    /* System Port AによるA20ライン有効化 */
+    A20EnableBySysPortA();
+    
+    /* A20ライン有効化判定 */
+    ret = A20CheckEnable();
+    
+    /* 有効化判定 */
+    if ( ret == CMN_SUCCESS ) {
+        /* 有効 */
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ );
+        
+        return CMN_SUCCESS;
+    }
+    
+    /* キーボードコントローラによるA20ライン有効化 */
+    A20EnableByKbc();
+    
+    /* A20ライン有効化判定 */
+    ret = A20CheckEnable();
+    
+    /* 有効化判定 */
+    if ( ret == CMN_SUCCESS ) {
+        /* 有効 */
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ );
+        
+        return CMN_SUCCESS;
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ );
+    
+    return CMN_FAILURE;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       A20ライン有効化チェック
+ * @details     A20ラインが有効でメモリが1MiB以上アクセス可能かチェックする。
+ * 
+ * @retval      CMN_SUCCESS 有効
+ * @retval      CMN_FAILURE 無効
+ */
+/******************************************************************************/
+static CmnRet_t A20CheckEnable( void )
+{
+    volatile uint16_t backup;    /* バックアップ値 */
+    volatile uint16_t check;     /* チェック値     */
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* アドレス0x0010_0000(または0x0000_0000)を2byte分バックアップ */
+    backup = *( ( volatile uint16_t * ) 0x00100000 );
+    
+    /* CPUキャッシング無効化 */
+    IA32InstructionSetCr0( IA32_CR0_CD, IA32_CR0_CD | IA32_CR0_NW );
+    IA32InstructionWbinvd();
+    
+    /* アドレス0x0010_0000の2byte書き込み */
+    *( ( volatile uint16_t * ) 0x00100000 ) = 0xC0DE;
+    
+    /* アドレス0x0000_0000の2byte読み込み */
+    check = *( ( volatile uint16_t * ) 0x00000000 );
+    
+    /* アドレス0x0010_0000(または0x0000_0000)を2byte分リストア */
+    *( ( volatile uint16_t * ) 0x00100000 ) = backup;
+    
+    /* CPUキャッシュ有効化 */
+    IA32InstructionSetCr0( 0, IA32_CR0_CD | IA32_CR0_NW );
+    
+    /* A20ライン有効判定 */
+    if ( check == 0xC0DE ) {
+        /* 無効 */
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ );
+        
+        return CMN_FAILURE;
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ );
+    
+    /* A20ライン有効 */
+    return CMN_SUCCESS;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       A20ライン有効化(System Port A)
+ * @details     System Port Aを用いてA20ラインを有効化する。
+ */
+/******************************************************************************/
+static void A20EnableBySysPortA( void )
+{
+    uint8_t value;
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* System Port A の設定値取得 */
+    IA32InstructionInByte( &value, 0x92 );
+    
+    /* A20ライン有効化 */
+    value |= 0x02;
+    
+    /* システムリセット抑止 */
+    value &= 0xFE;
+    
+    /* System Port A に設定 */
+    IA32InstructionOutByte( 0x92, value );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       A20ライン有効化(Keyboard Controller)
+ * @details     キーボードコントローラを用いてA20ラインを有効化する。
+ */
+/******************************************************************************/
+static void A20EnableByKbc( void )
+{
+    uint8_t value;
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* コマンド入力待ち */
+    do {
+        /* IBF設定値取得 */
+        IA32InstructionInByte( &value, 0x64 );
+        
+    } while ( !MLIB_BASIC_HAVE_FLAG( value, 0x02 ) );
+    
+    /* コマンド書き込み */
+    IA32InstructionOutByte( 0x64, 0xD1 );
+    
+    /* コマンド入力待ち */
+    do {
+        /* IBF設定値取得 */
+        IA32InstructionInByte( &value, 0x64 );
+        
+    } while ( !MLIB_BASIC_HAVE_FLAG( value, 0x02 ) );
+    
+    /* A20ライン有効化 */
+    IA32InstructionOutByte( 0x60, 0xDF );
+    
+    /* コマンド入力待ち */
+    do {
+        /* IBF設定値取得 */
+        IA32InstructionInByte( &value, 0x64 );
+        
+    } while ( !MLIB_BASIC_HAVE_FLAG( value, 0x02 ) );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/Driver/DriverAta.c b/src/booter/Driver/DriverAta.c
new file mode 100644 (file)
index 0000000..2ac7c68
--- /dev/null
@@ -0,0 +1,323 @@
+/******************************************************************************/
+/* src/booter/Driver/DriverAta.c                                              */
+/*                                                                 2017/07/11 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stddef.h>
+#include <stdint.h>
+#include <hardware/ATA/ATA.h>
+#include <hardware/IA32/IA32Instruction.h>
+#include <hardware/I8259A/I8259A.h>
+#include <MLib/Basic/MLibBasic.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <Driver.h>
+#include <IntMng.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                   \
+    DebugLogOutput( CMN_MODULE_DRIVER_ATA, \
+                    __LINE__,              \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/** リトライ最大回数 */
+#define ATA_RETRY        ( 50000 )
+
+/* 割込みフラグ */
+#define ATA_INT_FLAG_ON  ( 1 )      /** 割込みフラグON  */
+#define ATA_INT_FLAG_OFF ( 0 )      /** 割込みフラグOFF */
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+/* 状態待ち合わせ */
+static void AtaWaitStatus( uint8_t mask,
+                           uint8_t status );
+/* 割込み待ち合わせ */
+static void AtaWaitInterrupt( void );
+
+
+/******************************************************************************/
+/* グローバル変数定義                                                         */
+/******************************************************************************/
+/** 割込みフラグ */
+static volatile uint32_t gInterruptFlag;
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief           ATAドライバ初期化
+ * @details         ATAドライバを初期化する。
+ */
+/******************************************************************************/
+void DriverAtaInit( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* 割込みフラグ初期化 */
+    gInterruptFlag = ATA_INT_FLAG_OFF;
+    
+    /* 割込み許可設定 */
+    IntMngPicAllowIrq( I8259A_IRQ14 );
+    
+    /* 割込みハンドラ登録 */
+    IntMngHdlSet( INTMNG_PIC_VCTR_BASE + I8259A_IRQ14,
+                  DriverAtaHandler );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       ATA割込みハンドラ
+ * @details     ATAからの割込みを処理する。
+ * 
+ * @param[in]   intNo 割込み番号
+ */
+/******************************************************************************/
+void DriverAtaHandler( uint32_t intNo )
+{
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() start. intNo=%#X", __func__, intNo );*/
+    
+    /* 割込みフラグ設定 */
+    gInterruptFlag = ATA_INT_FLAG_ON;
+    
+    /* EOI命令発行 */
+    IntMngPicEoi( I8259A_IRQ14 );
+    
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() end.", __func__ );*/
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief           ディスク読み込み
+ * @details         ディスクからデータを読み込む
+ * 
+ * @param[in/out]   *pAddr データ格納先アドレス
+ * @param[in]       lba    ディスク上アドレス(LBA)
+ * @param[in]       size   読み込みサイズ(セクタ)
+ */
+/******************************************************************************/
+CmnRet_t DriverAtaRead( void     *pAddr,
+                        uint32_t lba,
+                        size_t   size    )
+{
+    uint8_t           status;        /* Status レジスタ値     */
+    volatile uint32_t sectorCnt;     /* 1コマンド読込みサイズ */
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start. *pAddr=%p, lba=%#X, size=%u",
+               __func__,
+               pAddr,
+               lba,
+               size );
+    
+    /* 1コマンド毎に繰り返し */
+    while ( size > 0 ) {
+        /* アイドル状態待ち合わせ */
+        AtaWaitStatus( ATA_STATUS_BSY | ATA_STATUS_DRQ, 0 );
+        
+        /* デバイスアドレス設定 */
+        IA32InstructionOutByte( ATA_PORT_DEV_HEAD, 0 );
+        
+        /* アイドル状態待ち合わせ */
+        AtaWaitStatus( ATA_STATUS_BSY | ATA_STATUS_DRQ, 0 );
+        
+        /* Featuresレジスタ設定 */
+        IA32InstructionOutByte( ATA_PORT_FEATURES, 0 );
+        
+        /* LBA設定 */
+        IA32InstructionOutByte( ATA_PORT_DEV_HEAD,
+                                ATA_DEV_HEAD_LBA | ATA_LBA_TO_DEV_HEAD( lba ) );
+        IA32InstructionOutByte( ATA_PORT_CYL_HIGH,
+                                ATA_LBA_TO_CYL_HIGH( lba ) );
+        IA32InstructionOutByte( ATA_PORT_CYL_LOW,
+                                ATA_LBA_TO_CYL_LOW( lba ) );
+        IA32InstructionOutByte( ATA_PORT_SECTOR_NUM,
+                                ATA_LBA_TO_SECTOR_NUM( lba ) );
+        
+        /* 読込みサイズ判定 */
+        if ( size >= ATA_SECTOR_CNT_MAX ) {
+            /* Sector Count 最大値以上 */
+            
+            /* 設定 */
+            sectorCnt  = ATA_SECTOR_CNT_MAX;    /* Sector Count */
+            size      -= ATA_SECTOR_CNT_MAX;    /* 読込みサイズ */
+            lba       += ATA_SECTOR_CNT_MAX;    /* LBA          */
+            
+            /* サイズ設定 */
+            IA32InstructionOutByte( ATA_PORT_SECTOR_CNT, 0 );
+            
+        } else {
+            /* Sector Count 最大値未満 */
+            
+            /* 設定 */
+            sectorCnt = size;                   /* Sector Count */
+            size      = 0;                      /* 読込みサイズ */
+            
+            /* サイズ設定 */
+            IA32InstructionOutByte( ATA_PORT_SECTOR_CNT, sectorCnt );
+        }
+        
+        /* 割込みフラグOFF */
+        gInterruptFlag = ATA_INT_FLAG_OFF;
+        
+        /* コマンド書き込み */
+        IA32InstructionOutByte( ATA_PORT_COMMAND, ATA_CMD_READ_SECTOR );
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "%s() command write. cnt=%u", __func__, sectorCnt );
+        
+        /* 1セクタサイズ毎繰り返し */
+        for ( ; sectorCnt > 0; sectorCnt-- ) {
+            /* 割り込み待ち合わせ */
+            AtaWaitInterrupt();
+            
+            /* アイドル状態待ち合わせ */
+            AtaWaitStatus( ATA_STATUS_BSY, 0 );
+            
+            /* ステータスレジスタ取得 */
+            IA32InstructionInByte( &status, ATA_PORT_STATUS );
+            
+            /* 割込みフラグOFF */
+            gInterruptFlag = ATA_INT_FLAG_OFF;
+            
+            /* データ転送要求有無判定 */
+            if ( MLIB_BASIC_HAVE_FLAG( status, ATA_STATUS_DRQ ) ) {
+                /* データ転送要求有 */
+                
+                /* デバッグトレースログ出力 */
+                DEBUG_LOG( "%s() read. pAddr=%p, sectorCnt=%u.",
+                           __func__,
+                           pAddr,
+                           sectorCnt );
+                
+                /* データ転送 */
+                IA32InstructionRepInsw( pAddr,
+                                        ATA_PORT_DATA,
+                                        ATA_TRANSFER_COUNT );
+                
+                /* 格納先アドレス更新 */
+                pAddr += ATA_TRANSFER_COUNT * 2;
+                
+            } else {
+                /* データ転送要求無 */
+                
+                /* デバッグトレースログ出力 */
+                DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ );
+                
+                return CMN_FAILURE;
+            }
+            
+            /* 1PIO転送サイクル待ち */
+            IA32InstructionInByte( &status, ATA_PORT_ALT_STATUS );
+        }
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ );
+    
+    return CMN_SUCCESS;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief           状態待ち合わせ
+ * @details         Statusレジスタが指定状態になるのを待ち合わせる。
+ * 
+ * @param[in]       mask   レジスタマスク値
+ * @param[in]       status 状態
+ */
+/******************************************************************************/
+static void AtaWaitStatus( uint8_t mask,
+                           uint8_t status )
+{
+    uint8_t  value;     /* Statusレジスタ値 */
+    uint32_t retry;     /* リトライ回数     */
+    
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() start. mask=%#X, status=%#X", __func__, mask, status );*/
+    
+    /* アイドル状態になるまで繰り返し */
+    for ( retry = 0; retry <= ATA_RETRY; retry++ ) {
+        /* Statusレジスタ読込 */
+        IA32InstructionInByte( &value, ATA_PORT_STATUS );
+        
+        /* 状態判定 */
+        if ( ( value & mask ) == status ) {
+            /* 状態一致 */
+            
+            /* デバッグトレースログ出力 *//*
+            DEBUG_LOG( "%s() end." );*/
+            
+            return;
+        }
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() retry out.", __func__ );
+    
+    /* アボート */
+    CmnAbort();
+}
+
+
+/******************************************************************************/
+/**
+ * @brief           割込み待ち合わせ
+ * @details         ATAデバイスから割り込みが発生するのを待ち合わせる。
+ */
+/******************************************************************************/
+static void AtaWaitInterrupt( void )
+{
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() start.", __func__ );*/
+    
+    /* 割込みが発生するまで繰り返し */
+    while ( gInterruptFlag == ATA_INT_FLAG_OFF ) {
+        /* 未発生 */
+        
+        /* hlt命令実行 */
+        IA32InstructionHlt();
+    }
+    
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() end.", __func__ );*/
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/Driver/DriverAta.h b/src/booter/Driver/DriverAta.h
new file mode 100644 (file)
index 0000000..35be2e8
--- /dev/null
@@ -0,0 +1,16 @@
+/******************************************************************************/
+/* src/booter/Driver/DriverAta.h                                              */
+/*                                                                 2017/06/26 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef DRIVER_ATA_H
+#define DRIVER_ATA_H
+/******************************************************************************/
+/* グローバル関数宣言                                                         */
+/******************************************************************************/
+/* ATAドライバ初期化 */
+extern void DriverAtaInit( void );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/Driver/DriverInit.c b/src/booter/Driver/DriverInit.c
new file mode 100644 (file)
index 0000000..13f1cc3
--- /dev/null
@@ -0,0 +1,55 @@
+/******************************************************************************/
+/* src/booter/Driver/DriverInit.c                                             */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+
+/* 内部モジュールヘッダ */
+#include "DriverAta.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                    \
+    DebugLogOutput( CMN_MODULE_DRIVER_INIT, \
+                    __LINE__,               \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       ドライバ初期化
+ * @details     各ドライバを初期化する。
+ */
+/******************************************************************************/
+void DriverInit( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* ATAドライバ初期化 */
+    DriverAtaInit();
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
similarity index 68%
rename from src/booter/Initctrl/InitctrlCpu.s
rename to src/booter/InitCtrl/InitCtrlInit16.s
index 9ba9a6e..53aab26 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
-/* src/booter/Initctrl/InitctrlCpu.s                                          */
-/*                                                                 2017/03/12 */
+/* src/booter/InitCtrl/InitCtrlInit16.s                                       */
+/*                                                                 2017/06/27 */
 /* Copyright (C) 2016-2017 Mochi.                                             */
 /******************************************************************************/
  .intel_syntax noprefix
@@ -8,7 +8,13 @@
 /******************************************************************************/
 /* グローバル宣言                                                             */
 /******************************************************************************/
-.global CpuSwitchMode
+.global InitCtrlInit16
+
+
+/******************************************************************************/
+/* 外部関数宣言                                                               */
+/******************************************************************************/
+.extern IntCtrlInit32
 
 
 /******************************************************************************/
 /******************************************************************************/
 .section .text
 
-CpuSwitchMode:
+InitCtrlInit16:
+    /* 初期化 */
+    xor         ax, ax
+    mov         ds, ax
+    mov         es, ax
+    mov         fs, ax
+    mov         gs, ax
+    
+    /* ビデオモード設定 */
+    mov         ax, 0x0003
+    int         0x10
+    
     /* 割り込み無効化 */
     mov         al, 0xFF
     out         0xA1, al        /* PIC2割り込み無効化 */
@@ -25,7 +42,7 @@ CpuSwitchMode:
     cli                         /* CPU割り込み無効化  */
     
     /* GDT設定 */
-    lgdt        [ pGDTR ]
+    lgdt        [ gInitGdtr ]
     
     /* CR0レジスタ設定 */
     mov         eax, cr0
@@ -33,10 +50,10 @@ CpuSwitchMode:
     mov         cr0, eax        /* 保護モード有効化 */
     
     /* 保護モード移行(far jump) */
-    jmp         0x8:setSegment
+    jmp         0x8:InitSetSegment
     
 .code32
-setSegment:
+InitSetSegment:
     /* データセグメント初期化 */
     mov         ax, 2 * 8
     mov         ds, ax
@@ -46,10 +63,14 @@ setSegment:
     mov         ss, ax
     
     /* スタックポインタ変更 */
-    mov         esp, 0x04000000
+    mov         esp, 0xA0000 - 4
+    
+    /* 保護モード初期化関数呼び出し */
+    call        InitCtrlInit32
     
-    /* カーネル実行 */
-    jmp         0x00100000
+InitStop:
+    hlt
+    jmp         InitStop
 
 
 /******************************************************************************/
@@ -58,15 +79,15 @@ setSegment:
 .section .data
 /* GDT */
 .align 8
-pGDT:
+gInitGdt:
     .word   0x0000, 0x0000, 0x0000, 0x0000  /* ナルセグメント   */
     .word   0xFFFF, 0x0000, 0x9800, 0x00CF  /* コードセグメント */
     .word   0xFFFF, 0x0000, 0x9200, 0x00CF  /* データセグメント */
 
 /* GDTR */
-pGDTR:
-    .word   . - pGDT - 1     /* リミット          */
-    .long   pGDT             /* GDTベースアドレス */
+gInitGdtr:
+    .word   . - gInitGdt - 1    /* リミット          */
+    .long   gInitGdt            /* GDTベースアドレス */
 
 
 /******************************************************************************/
diff --git a/src/booter/InitCtrl/InitCtrlInit32.c b/src/booter/InitCtrl/InitCtrlInit32.c
new file mode 100644 (file)
index 0000000..67509a4
--- /dev/null
@@ -0,0 +1,108 @@
+/******************************************************************************/
+/* src/booter/InitCtrl/InitCtrlInit32.c                                       */
+/*                                                                 2017/07/11 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stddef.h>
+#include <hardware/IA32/IA32Instruction.h>
+#include <kernel/MochiKernel.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <Driver.h>
+#include <IntMng.h>
+#include <LoadMng.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                  \
+    DebugLogOutput( CMN_MODULE_INIT_INIT, \
+                    __LINE__,             \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/* カーネルメイン関数 */
+void ( *MochiKernelMain )( void ) = ( void * ) MOCHIKERNEL_ADDR_ENTRY;
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       初期化(32bitモード)
+ * @details     初期化してカーネルを読込み起動する。
+ */
+/******************************************************************************/
+void InitCtrlInit32( void )
+{
+    CmnRet_t ret;   /* 関数戻り値 */
+    
+    /* デバッグ制御初期化 */
+    DebugInit();
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "MochiBooter start." );
+    
+    /* A20ライン有効化 */
+    ret = DriverA20Enable();
+    
+    /* 有効化結果判定 */
+    if ( ret != CMN_SUCCESS ) {
+        /* 失敗 */
+        
+        /* デバッグトレースログ出力 */
+        DEBUG_LOG( "DriverA20Enable() Failure. ret=%u", ret );
+        
+        /* アボート */
+        CmnAbort();
+    }
+    
+    /* 割り込み管理初期化 */
+    IntMngInit();
+    
+    /* ドライバ初期化 */
+    DriverInit();
+    
+    /* 割込み有効化 */
+    IntMngPicEnable();
+    IA32InstructionSti();
+    
+    /* ロード管理初期化 */
+    LoadMngInit();
+    
+    /* カーネル読込み */
+    LoadMngKernelLoad();
+    
+    /* 割込み無効化 */
+    IA32InstructionCli();
+    IntMngPicDisable();
+    
+    /* スタックポインタ再設定 */
+    IA32InstructionSetEsp( MOCHIKERNEL_ADDR_STACK );
+    
+    MochiKernelMain();
+    
+    /* トレースログ出力 */
+    DEBUG_LOG( "%s() end. error.", __func__ );
+    
+    CmnAbort();
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/Initctrl/InitctrlA20.s b/src/booter/Initctrl/InitctrlA20.s
deleted file mode 100644 (file)
index 60b48a0..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/******************************************************************************/
-/* src/booter/Initctrl/InitctrlA20.s                                          */
-/*                                                                 2017/03/12 */
-/* Copyright (C) 2016-2017 Mochi.                                             */
-/******************************************************************************/
- .intel_syntax noprefix
-.code16
-/******************************************************************************/
-/* グローバル宣言                                                             */
-/******************************************************************************/
-.global A20Enable
-
-
-/******************************************************************************/
-/* TEXTセクション                                                             */
-/******************************************************************************/
-.section .text
-/******************************************************************************/
-/* グローバル関数                                                             */
-/******************************************************************************/
-A20Enable:
-    /* A20ライン有効化判定 */
-    call        CheckA20
-    cmp         ax, 0
-    je          A20Enable_0
-    
-    /* System Port Aを用いて有効化 */
-    in          al, 0x92
-    or          al, 0x02        /* 有効化                       */
-    and         al, 0xFE        /* システムリセットを確実に防ぐ */
-    out         0x92, al        /* 設定                         */
-    
-    /* A20ライン有効化判定 */
-    call        CheckA20
-    cmp         ax, 0
-    je          A20Enable_0
-    
-    /* キーボードコントローラを用いて有効化 */
-    call        waitKBC     /* 入力受付確認   */
-    mov         al, 0xD1
-    out         0x64, al    /* コマンド書込み */
-    call        waitKBC     /* 入力受付確認   */
-    mov         al, 0xDF
-    out         0x60, al    /* 有効化         */
-    call        waitKBC     /* 入力受付確認   */
-    
-    /* A20ライン有効化判定 */
-    call        CheckA20
-    cmp         ax, 0
-    je          A20Enable_0
-    
-    /* BIOSを用いて有効化 */
-    mov         ax, 0x2401
-    int         0x15
-    
-    /* A20ライン有効化判定 */
-    call        CheckA20
-    cmp         ax, 0
-    je          A20Enable_0
-    
-A20Enable_0:
-    /* A20ライン有効化失敗 */
-    mov         ax, -1
-    ret
-A20Enable_M1:
-    /* A20ライン有効化成功 */
-    xor         ax, ax
-    ret
-
-
-/******************************************************************************/
-/* ローカル関数                                                               */
-/******************************************************************************/
-CheckA20:
-    /* 0xFFFF:0x0010(0x0010_0000)をバックアップ */
-    mov         ax, 0xFFFF
-    mov         fs, ax
-    mov         ax, [ fs:0x0010 ]
-    push        ax
-    
-    /* CPUキャッシング無効化 */
-    mov         eax, cr0            /* CR0レジスタ取得              */
-    or          eax, 0x40000000     /* CDビットを1に設定            */
-    and         eax, 0xD0000000     /* NWビットを0に設定            */
-    mov         cr0, eax            /* CR0レジスタに設定して無効化  */
-    wbinvd                          /* キャッシュメモリライトバック */
-    
-    /* 0xFFFF:0x0010(0x0010_0000)に値0xC0DE書き込み */
-    mov         word ptr [ fs:0x0010 ], 0xC0DE
-    
-    /* 0x0000:0x0000(0x0000_0000)の値を読み込む */
-    xor         ax, ax
-    mov         gs, ax
-    mov         bx, [ gs:0x0000 ]
-    
-    /* 0xFFFF:0x0010(0x0010_0000)をリストア */
-    pop         ax
-    mov         [ fs:0x0010 ], ax
-    
-    /* CPUキャッシング有効化 */
-    mov         eax, cr0            /* CR0レジスタ取得             */
-    or          eax, 0x60000000     /* CD,NWビットを1に設定        */
-    mov         cr0, eax            /* CR0レジスタに設定して有効化 */
-    
-    /* 読み込んだ値と比較 */
-    cmp         bx, 0xC0DE
-    je          checkA20_M1
-    
-    /* A20ラインは有効 */
-    xor         ax, ax
-    ret
-checkA20_M1:
-    /* A20ラインは無効 */
-    mov         ax, -1
-    ret
-
-waitKBC:
-    /* IBFチェック */
-    in          al, 0x64
-    test        al, 0x02
-    jnz         waitKBC
-    ret
-
-
-/******************************************************************************/
diff --git a/src/booter/Initctrl/InitctrlMain.s b/src/booter/Initctrl/InitctrlMain.s
deleted file mode 100644 (file)
index 0f0e286..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/******************************************************************************/
-/* src/booter/Initctrl/InitctrlMain.s                                         */
-/*                                                                 2017/03/12 */
-/* Copyright (C) 2016-2017 Mochi.                                             */
-/******************************************************************************/
- .intel_syntax noprefix
-.code16
-/******************************************************************************/
-/* グローバル宣言                                                             */
-/******************************************************************************/
-.global InitctrlMain
-
-
-/******************************************************************************/
-/* 外部関数宣言                                                               */
-/******************************************************************************/
-.extern A20Enable
-.extern LoaderKernel
-.extern CpuSwitchMode
-
-
-/******************************************************************************/
-/* TEXTセクション                                                             */
-/******************************************************************************/
-.section .text
-
-InitctrlMain:
-    /* ビデオモード設定 */
-    mov         ax, 0x0003
-    int         0x10
-    
-    /* A20ライン有効化 */
-    call        A20Enable
-    
-    /* カーネル読込み */
-    call        LoaderLoadKernel
-    
-    /* CPUモード変更 */
-    call        CpuSwitchMode
-    
-Stop:
-    hlt
-    jmp         Stop
-
-/******************************************************************************/
diff --git a/src/booter/IntMng/IntMngHdl.c b/src/booter/IntMng/IntMngHdl.c
new file mode 100644 (file)
index 0000000..db6a08c
--- /dev/null
@@ -0,0 +1,248 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngHdl.c                                              */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+#include <hardware/IA32/IA32Descriptor.h>
+#include <hardware/IA32/IA32Instruction.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <IntMng.h>
+
+/* 内部モジュールヘッダ */
+#include "IntMngIdt.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                   \
+    DebugLogOutput( CMN_MODULE_INTMNG_HDL, \
+                    __LINE__,              \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/** 割込みハンドラ共通関数定義マクロ */
+#define HDL_CMN_PROC( _INT_NO )                             \
+    static void HdlCmnProc##_INT_NO( void )                 \
+    {                                                       \
+        /* コンテキスト保存 */                              \
+        IA32InstructionPushDs();                            \
+        IA32InstructionPushEs();                            \
+        IA32InstructionPushFs();                            \
+        IA32InstructionPushGs();                            \
+        IA32InstructionPushad();                            \
+                                                            \
+        /* 割込みハンドラ呼出し */                          \
+        IA32InstructionPush( _INT_NO );                     \
+        IA32InstructionCall( gHdlIntProcTbl[ _INT_NO ] );   \
+        IA32InstructionAddEsp( 4 );                         \
+                                                            \
+        /* コンテキスト復帰 */                              \
+        IA32InstructionPopad();                             \
+        IA32InstructionPopGs();                             \
+        IA32InstructionPopFs();                             \
+        IA32InstructionPopEs();                             \
+        IA32InstructionPopDs();                             \
+                                                            \
+        /* return */                                        \
+        IA32InstructionIretd();                             \
+    }
+
+/** 割込みハンドラ共通関数連続定義マクロ */
+#define HDL_CMN_PROC_16X( _X )  \
+    HDL_CMN_PROC( _X##0 )       \
+    HDL_CMN_PROC( _X##1 )       \
+    HDL_CMN_PROC( _X##2 )       \
+    HDL_CMN_PROC( _X##3 )       \
+    HDL_CMN_PROC( _X##4 )       \
+    HDL_CMN_PROC( _X##5 )       \
+    HDL_CMN_PROC( _X##6 )       \
+    HDL_CMN_PROC( _X##7 )       \
+    HDL_CMN_PROC( _X##8 )       \
+    HDL_CMN_PROC( _X##9 )       \
+    HDL_CMN_PROC( _X##A )       \
+    HDL_CMN_PROC( _X##B )       \
+    HDL_CMN_PROC( _X##C )       \
+    HDL_CMN_PROC( _X##D )       \
+    HDL_CMN_PROC( _X##E )       \
+    HDL_CMN_PROC( _X##F )
+
+/** 割込みハンドラ共通関数宣言連続定義マクロ */
+#define HDL_CMN_PROC_PROTOTYPE_16X( _X )    \
+    static void HdlCmnProc##_X##0( void );  \
+    static void HdlCmnProc##_X##1( void );  \
+    static void HdlCmnProc##_X##2( void );  \
+    static void HdlCmnProc##_X##3( void );  \
+    static void HdlCmnProc##_X##4( void );  \
+    static void HdlCmnProc##_X##5( void );  \
+    static void HdlCmnProc##_X##6( void );  \
+    static void HdlCmnProc##_X##7( void );  \
+    static void HdlCmnProc##_X##8( void );  \
+    static void HdlCmnProc##_X##9( void );  \
+    static void HdlCmnProc##_X##A( void );  \
+    static void HdlCmnProc##_X##B( void );  \
+    static void HdlCmnProc##_X##C( void );  \
+    static void HdlCmnProc##_X##D( void );  \
+    static void HdlCmnProc##_X##E( void );  \
+    static void HdlCmnProc##_X##F( void );
+
+
+/** 割込みハンドラ共通関数リスト連続定義マクロ */
+#define HDL_CMN_PROC_LIST_16X( _X ) \
+    HdlCmnProc##_X##0,              \
+    HdlCmnProc##_X##1,              \
+    HdlCmnProc##_X##2,              \
+    HdlCmnProc##_X##3,              \
+    HdlCmnProc##_X##4,              \
+    HdlCmnProc##_X##5,              \
+    HdlCmnProc##_X##6,              \
+    HdlCmnProc##_X##7,              \
+    HdlCmnProc##_X##8,              \
+    HdlCmnProc##_X##9,              \
+    HdlCmnProc##_X##A,              \
+    HdlCmnProc##_X##B,              \
+    HdlCmnProc##_X##C,              \
+    HdlCmnProc##_X##D,              \
+    HdlCmnProc##_X##E,              \
+    HdlCmnProc##_X##F
+
+/* 割込みハンドラ共通関数型 */
+typedef void ( *hdlCmnProc_t )( void );
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+/* 割込みハンドラ共通関数 */
+HDL_CMN_PROC_PROTOTYPE_16X( 0x0 )
+HDL_CMN_PROC_PROTOTYPE_16X( 0x1 )
+HDL_CMN_PROC_PROTOTYPE_16X( 0x2 )
+
+/* 無視割込みハンドラ */
+static void HdlIgnore( uint32_t intNo );
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/** 割込みハンドラ共通関数テーブル */
+const hdlCmnProc_t gHdlCmnProcTbl[ INTMNG_INT_NO_NUM ] = {
+    HDL_CMN_PROC_LIST_16X( 0x0 ),
+    HDL_CMN_PROC_LIST_16X( 0x1 ),
+    HDL_CMN_PROC_LIST_16X( 0x2 )  };
+
+/** 割込みハンドラ管理テーブル */
+static IntMngHdl_t gHdlIntProcTbl[ INTMNG_INT_NO_NUM ];
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       ハンドラ管理初期化
+ * @details     ハンドラ管理サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void IntMngHdlInit( void )
+{
+    uint32_t intNo;     /* 割込み番号 */
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* 全割込み番号毎に繰り返し */
+    for ( intNo =  INTMNG_INT_NO_MIN;
+          intNo <= INTMNG_INT_NO_MAX;
+          intNo++ ) {
+        /* 割込みハンドラ管理テーブル設定 */
+        gHdlIntProcTbl[ intNo ] = HdlIgnore;
+        
+        /* IDT登録 */
+        IntMngIdtSet(
+            intNo,                              /* IDTエントリ番号    */
+            1 * 8,                              /* セレクタ           */
+            gHdlCmnProcTbl[ intNo ],            /* オフセット         */
+            0,                                  /* 引数コピーカウント */
+            IA32_DESCRIPTOR_TYPE_GATE32_INT,    /* タイプ             */
+            IA32_DESCRIPTOR_DPL_0            ); /* 特権レベル         */
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       割込みハンドラ登録
+ * @details     割込みハンドラを登録する。
+ * 
+ * @param[in]   intNo 割込み番号
+ *                  - INTMNG_INT_NO_MIN 割込み番号最小値
+ *                  - INTMNG_INT_NO_MAX 割込み番号最大値
+ * @param[in]   func  割込みハンドラ
+ */
+/******************************************************************************/
+void IntMngHdlSet( uint32_t    intNo,
+                   IntMngHdl_t func )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start. intNo=%#X, func=%p", __func__, intNo, func );
+    
+    /* 割込みハンドラ管理テーブル設定 */
+    gHdlIntProcTbl[ intNo ] = func;
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+/* 割込みハンドラ共通関数 */
+HDL_CMN_PROC_16X( 0x0 )
+HDL_CMN_PROC_16X( 0x1 )
+HDL_CMN_PROC_16X( 0x2 )
+
+
+/******************************************************************************/
+/**
+ * @brief       無視割込みハンドラ
+ * @details     割込み処理として何もしない割込みハンドラ。
+ * 
+ * @param[in]   intNo 割込み番号
+ */
+/******************************************************************************/
+static void HdlIgnore( uint32_t intNo )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() intNo=%#X", __func__, intNo );
+    
+    while ( true ) {
+        IA32InstructionHlt();
+    }
+    
+    /* 何もしない */
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/IntMng/IntMngHdl.h b/src/booter/IntMng/IntMngHdl.h
new file mode 100644 (file)
index 0000000..e151282
--- /dev/null
@@ -0,0 +1,16 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngHdl.h                                              */
+/*                                                                 2017/06/20 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef INTMNG_HDL_H
+#define INTMNG_HDL_H
+/******************************************************************************/
+/* グローバル関数宣言                                                         */
+/******************************************************************************/
+/* ハンドラ管理初期化 */
+extern void IntMngHdlInit( void );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/IntMng/IntMngIdt.c b/src/booter/IntMng/IntMngIdt.c
new file mode 100644 (file)
index 0000000..19eb7f2
--- /dev/null
@@ -0,0 +1,137 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngIdt.c                                              */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <string.h>
+#include <hardware/IA32/IA32Descriptor.h>
+#include <hardware/IA32/IA32Instruction.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <IntMng.h>
+
+/* 内部モジュールヘッダ */
+#include "IntMngIdt.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                   \
+    DebugLogOutput( CMN_MODULE_INTMNG_IDT, \
+                    __LINE__,              \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/* IDT */
+static IA32DescriptorGate_t gIdt[ INTMNG_IDT_ENTRY_NUM ];
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       IDT管理初期化
+ * @details     IDT管理サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void IntMngIdtInit( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* IDT初期化 */
+    memset( gIdt, 0, sizeof ( gIdt ) );
+    
+    /* IDTR設定 */
+    IA32InstructionLidt( ( IA32Descriptor_t * ) gIdt, sizeof ( gIdt ) - 1 );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       IDTエントリ設定
+ * @details     IDTにエントリを設定する。
+ * 
+ * @param[in]   index    IDTエントリ番号
+ *                  - INTMNG_IDT_ENTRY_MIN 割込み番号(最小値)
+ *                  - INTMNG_IDT_ENTRY_MAX 割込み番号(最大値)
+ * @param[in]   selector セレクタ
+ * @param[in]   *pOffset オフセット
+ * @param[in]   count    引数コピーカウント
+ * @param[in]   type     タイプ
+ *                  - IA32_DESCRIPTOR_TYPE_TSS16       16bitTSS
+ *                  - IA32_DESCRIPTOR_TYPE_LDT         LDT
+ *                  - IA32_DESCRIPTOR_TYPE_TSS16_BUSY  16bitTSS(ビジー)
+ *                  - IA32_DESCRIPTOR_TYPE_GATE16_CALL 16bitコールゲート
+ *                  - IA32_DESCRIPTOR_TYPE_GATE_TASK   タスクゲート
+ *                  - IA32_DESCRIPTOR_TYPE_GATE16_INT  16bit割込みゲート
+ *                  - IA32_DESCRIPTOR_TYPE_GATE16_TRAP 16bitトラップゲート
+ *                  - IA32_DESCRIPTOR_TYPE_TSS32       32bitTSS
+ *                  - IA32_DESCRIPTOR_TYPE_TSS32_BUSY  32bitTSS(ビジー)
+ *                  - IA32_DESCRIPTOR_TYPE_GATE32_CALL 32bitコールゲート
+ *                  - IA32_DESCRIPTOR_TYPE_GATE32_INT  32bit割込みゲート
+ *                  - IA32_DESCRIPTOR_TYPE_GATE32_TRAP 32bitトラップゲート
+ * @param[in]   level    特権レベル
+ *                  - IA32_DESCRIPTOR_DPL_0 特権レベル0
+ *                  - IA32_DESCRIPTOR_DPL_1 特権レベル1
+ *                  - IA32_DESCRIPTOR_DPL_2 特権レベル2
+ *                  - IA32_DESCRIPTOR_DPL_3 特権レベル3
+ */
+/******************************************************************************/
+void IntMngIdtSet( uint32_t index,
+                   uint16_t selector,
+                   void     *pOffset,
+                   uint8_t  count,
+                   uint8_t  type,
+                   uint8_t  level )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    DEBUG_LOG( " index=%#X, selector=%#X, pOffset=%#p,",
+               index,
+               selector,
+               pOffset );
+    DEBUG_LOG( " count=%#X, type=%#X, level=%#X",
+               count,
+               type,
+               level );
+    
+    /* ディスクリプタ設定 */
+    gIdt[ index ].offset_low  = IA32_DESCRIPTOR_OFFSET_LOW( pOffset );
+    gIdt[ index ].selector    = selector;
+    gIdt[ index ].count       = count;
+    gIdt[ index ].attr_type   = type;
+    gIdt[ index ].attr_s      = IA32_DESCRIPTOR_S_SYSTEM;
+    gIdt[ index ].attr_dpl    = level;
+    gIdt[ index ].attr_p      = IA32_DESCRIPTOR_P_YES;
+    gIdt[ index ].offset_high = IA32_DESCRIPTOR_OFFSET_HIGH( pOffset );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/IntMng/IntMngIdt.h b/src/booter/IntMng/IntMngIdt.h
new file mode 100644 (file)
index 0000000..06a76ed
--- /dev/null
@@ -0,0 +1,41 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngIdt.h                                              */
+/*                                                                 2017/06/20 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef INTMNG_IDT_H
+#define INTMNG_IDT_H
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdint.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* IDT定義 */
+#define INTMNG_IDT_ENTRY_MIN (    0 )   /**< IDTエントリ番号最小値 */
+#define INTMNG_IDT_ENTRY_MAX ( 0x2F )   /**< IDTエントリ番号最大値 */
+#define INTMNG_IDT_ENTRY_NUM \
+    ( INTMNG_IDT_ENTRY_MAX + 1 )        /**< IDTエントリ数         */
+
+
+/******************************************************************************/
+/* グローバル関数宣言                                                         */
+/******************************************************************************/
+/* IDT管理初期化 */
+extern void IntMngIdtInit( void );
+
+/* IDTエントリ設定 */
+extern void IntMngIdtSet( uint32_t index,
+                          uint16_t selector,
+                          void     *pOffset,
+                          uint8_t  count,
+                          uint8_t  type,
+                          uint8_t  level );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/IntMng/IntMngInit.c b/src/booter/IntMng/IntMngInit.c
new file mode 100644 (file)
index 0000000..4c37c5f
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngInit.c                                             */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+
+/* 内部モジュールヘッダ */
+#include "IntMngHdl.h"
+#include "IntMngIdt.h"
+#include "IntMngPic.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                    \
+    DebugLogOutput( CMN_MODULE_INTMNG_INIT, \
+                    __LINE__,               \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       割込み管理初期化
+ * @details     割込み管理内サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void IntMngInit( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* IDT管理サブモジュール初期化 */
+    IntMngIdtInit();
+    
+    /* ハンドラ管理サブモジュール初期化 */
+    IntMngHdlInit();
+    
+    /* PIC管理サブモジュール初期化 */
+    IntMngPicInit();
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/IntMng/IntMngPic.c b/src/booter/IntMng/IntMngPic.c
new file mode 100644 (file)
index 0000000..251f9cc
--- /dev/null
@@ -0,0 +1,348 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngPic.c                                              */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+#include <hardware/IA32/IA32Instruction.h>
+#include <hardware/I8259A/I8259A.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+
+/* 内部モジュールヘッダ */
+#include "IntMng.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                   \
+    DebugLogOutput( CMN_MODULE_INTMNG_PIC, \
+                    __LINE__,              \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/* 割込みマスク状態定義 */
+#define PIC_MASK_STATE_DISABLE ( 0 )    /**< マスク無効状態 */
+#define PIC_MASK_STATE_ENABLE  ( 1 )    /**< マスク有効状態 */
+
+/* PIC定義 */
+#define PIC_NUM                ( 2 )    /**< PIC数        */
+#define PIC_MASTER             ( 0 )    /**< PIC1マスタ   */
+#define PIC_SLAVE              ( 1 )    /**< PIC2スレーブ */
+
+/** PIC管理テーブル型 */
+typedef struct {
+    uint8_t maskState;          /**< PICマスク状態 */
+    uint8_t mask[ PIC_NUM ];    /**< PICマスク値   */
+    uint8_t reserved;           /**< パディング    */
+} picTbl_t;
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/** PIC管理テーブル */
+static picTbl_t gPicTbl;
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       PIC管理初期化
+ * @details     PIC管理サブモジュールの初期化を行う。
+ */
+/******************************************************************************/
+void IntMngPicInit( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* PIC2(スレーブ)設定 */
+    IA32InstructionOutByte( I8259A_S_PORT_ICW1, 0x11 );
+    IA32InstructionOutByte( I8259A_S_PORT_ICW2, 0x28 );
+    IA32InstructionOutByte( I8259A_S_PORT_ICW3, 0x02 );
+    IA32InstructionOutByte( I8259A_S_PORT_ICW4, 0x01 );
+    
+    /* PIC1(マスタ)設定 */
+    IA32InstructionOutByte( I8259A_M_PORT_ICW1, 0x11 );
+    IA32InstructionOutByte( I8259A_M_PORT_ICW2, 0x20 );
+    IA32InstructionOutByte( I8259A_M_PORT_ICW3, 0x04 );
+    IA32InstructionOutByte( I8259A_M_PORT_ICW4, 0x01 );
+    
+    /* PIC管理テーブル初期化 */
+    gPicTbl.mask[ PIC_MASTER ] = 0xFF;
+    gPicTbl.mask[ PIC_SLAVE  ] = 0xFF;
+    
+    /* 割込み無効化 */
+    IntMngPicDisable();
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       PIC割込み許可
+ * @details     PICに指定したIRQ番号の割込み許可設定を行う。
+ * 
+ * @param[in]   irqNo IRQ番号
+ *                  - I8259A_IRQ0  IRQ0
+ *                  - I8259A_IRQ1  IRQ1
+ *                  - I8259A_IRQ2  IRQ2
+ *                  - I8259A_IRQ3  IRQ3
+ *                  - I8259A_IRQ4  IRQ4
+ *                  - I8259A_IRQ5  IRQ5
+ *                  - I8259A_IRQ6  IRQ6
+ *                  - I8259A_IRQ7  IRQ7
+ *                  - I8259A_IRQ8  IRQ8
+ *                  - I8259A_IRQ9  IRQ9
+ *                  - I8259A_IRQ10 IRQ10
+ *                  - I8259A_IRQ11 IRQ11
+ *                  - I8259A_IRQ12 IRQ12
+ *                  - I8259A_IRQ13 IRQ13
+ *                  - I8259A_IRQ14 IRQ14
+ *                  - I8259A_IRQ15 IRQ15
+ */
+/******************************************************************************/
+void IntMngPicAllowIrq( uint8_t irqNo )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start. irqNo=%#X", __func__, irqNo );
+    
+    /* PIC割込み番号判定 */
+    if ( ( irqNo >= I8259A_IRQ0 ) &&
+         ( irqNo <= I8259A_IRQ7 )    ) {
+        /* PIC1(マスタ)向け割込み番号 */
+        
+        /* PIC1(マスタ)用マスク設定 */
+        gPicTbl.mask[ PIC_MASTER ] &= ~( 0x01 << irqNo );
+        
+    } else {
+        /* PIC2(スレーブ)向け割込み番号 */
+        
+        /* PIC1(マスタ)用マスク設定 */
+        gPicTbl.mask[ PIC_MASTER ] &= ~I8259A_OCW1_M2;
+        
+        /* PIC2(スレーブ)用マスク設定 */
+        gPicTbl.mask[ PIC_SLAVE ]  &= ~( 0x01 << ( irqNo - I8259A_IRQ8 ) );
+    }
+    
+    /* PIC割込みマスク状態判定 */
+    if ( gPicTbl.maskState == PIC_MASK_STATE_ENABLE ) {
+        /* 割込み有効 */
+        
+        /* PIC割込みマスク設定 */
+        IntMngPicEnable();
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       PIC割込み拒否
+ * @details     PICに指定したIRQ番号の割込み拒否設定を行う。
+ * 
+ * @param[in]   irqNo IRQ番号
+ *                  - I8259A_IRQ0 IRQ0
+ *                  - I8259A_IRQ1 IRQ1
+ *                  - I8259A_IRQ2 IRQ2
+ *                  - I8259A_IRQ3 IRQ3
+ *                  - I8259A_IRQ4 IRQ4
+ *                  - I8259A_IRQ5 IRQ5
+ *                  - I8259A_IRQ6 IRQ6
+ *                  - I8259A_IRQ7 IRQ7
+ *                  - I8259A_IRQ8 IRQ8
+ *                  - I8259A_IRQ9 IRQ9
+ *                  - I8259A_IRQ10 IRQ10
+ *                  - I8259A_IRQ11 IRQ11
+ *                  - I8259A_IRQ12 IRQ12
+ *                  - I8259A_IRQ13 IRQ13
+ *                  - I8259A_IRQ14 IRQ14
+ *                  - I8259A_IRQ15 IRQ15
+ */
+/******************************************************************************/
+void IntMngPicDenyIrq( uint8_t irqNo )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start. irqNo=%#X", __func__, irqNo );
+    
+    /* PIC割込み番号判定 */
+    if ( ( irqNo >= I8259A_IRQ0 ) &&
+         ( irqNo <= I8259A_IRQ7 )    ) {
+        /* PIC1(マスタ)向け割込み番号 */
+        
+        /* PIC1(マスタ)用マスク設定 */
+        gPicTbl.mask[ PIC_MASTER ] |= 0x01 << irqNo;
+        
+    } else {
+        /* PIC2(スレーブ)向け割込み番号 */
+        
+        /* PIC2(スレーブ)用マスク設定 */
+        gPicTbl.mask[ PIC_SLAVE ]  |= ( 0x01 << ( irqNo - I8259A_IRQ8 ) );
+        
+        /* PIC2(スレーブ)の全マスク判定 */
+        if ( gPicTbl.mask[ PIC_SLAVE ] == 0xFF ) {
+            /* 全マスク */
+            
+            /* PIC1(マスタ)用マスク設定 */
+            gPicTbl.mask[ PIC_MASTER ] |= I8259A_OCW1_M2;
+        }
+    }
+    
+    /* PIC割込みマスク状態判定 */
+    if ( gPicTbl.maskState == PIC_MASK_STATE_ENABLE ) {
+        /* 割込み有効 */
+        
+        /* PIC割込みマスク設定 */
+        IntMngPicEnable();
+    }
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       PIC割込み無効化
+ * @details     PIC割込みを無効化する。
+ */
+/******************************************************************************/
+void IntMngPicDisable( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* 割込みマスク状態変更 */
+    gPicTbl.maskState = PIC_MASK_STATE_DISABLE;
+    
+    /* PIC1(マスタ)割込みマスク設定 */
+    IA32InstructionOutByte( I8259A_M_PORT_OCW1, 0xFF );
+    
+    /* PIC2(スレーブ)割込みマスク設定 */
+    IA32InstructionOutByte( I8259A_S_PORT_OCW1, 0xFF );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       PIC割込み有効化
+ * @details     PIC割込みを有効化する。
+ */
+/******************************************************************************/
+void IntMngPicEnable( void )
+{
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* 割込みマスク状態変更 */
+    gPicTbl.maskState = PIC_MASK_STATE_ENABLE;
+    
+    /* PIC1(マスタ)割込みマスク設定 */
+    IA32InstructionOutByte( I8259A_M_PORT_OCW1, gPicTbl.mask[ PIC_MASTER ] );
+    
+    /* PIC2(スレーブ)割込みマスク設定 */
+    IA32InstructionOutByte( I8259A_S_PORT_OCW1, gPicTbl.mask[ PIC_SLAVE  ] );
+    
+    /* デバッグトレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       PIC割込みEOI通知
+ * @details     PICに指定したIRQ番号のEOI通知を行う。
+ * 
+ * @param[in]   irqNo IRQ番号
+ *                  - I8259A_IRQ0 IRQ0
+ *                  - I8259A_IRQ1 IRQ1
+ *                  - I8259A_IRQ2 IRQ2
+ *                  - I8259A_IRQ3 IRQ3
+ *                  - I8259A_IRQ4 IRQ4
+ *                  - I8259A_IRQ5 IRQ5
+ *                  - I8259A_IRQ6 IRQ6
+ *                  - I8259A_IRQ7 IRQ7
+ *                  - I8259A_IRQ8 IRQ8
+ *                  - I8259A_IRQ9 IRQ9
+ *                  - I8259A_IRQ10 IRQ10
+ *                  - I8259A_IRQ11 IRQ11
+ *                  - I8259A_IRQ12 IRQ12
+ *                  - I8259A_IRQ13 IRQ13
+ *                  - I8259A_IRQ14 IRQ14
+ *                  - I8259A_IRQ15 IRQ15
+ */
+/******************************************************************************/
+void IntMngPicEoi( uint8_t irqNo )
+{
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() start. irqNo=%#X", __func__, irqNo );*/
+    
+    /* PIC割込み番号判定 */
+    if ( ( irqNo >= I8259A_IRQ0 ) &&
+         ( irqNo <= I8259A_IRQ7 )    ) {
+        /* PIC1(マスタ)向け割込み番号 */
+        
+        /* PIC1(マスタ)EOI通知 */
+        IA32InstructionOutByte( I8259A_M_PORT_OCW2,
+                                I8259A_OCW2_SL  | 
+                                I8259A_OCW2_EOI |
+                                irqNo               );
+        
+    } else {
+        /* PIC2(スレーブ)向け割込み番号 */
+        
+        /* IRQ番号変換 */
+        irqNo -= I8259A_IRQ8;
+        
+        /* PIC2(スレーブ)EOI通知 */
+        IA32InstructionOutByte( I8259A_S_PORT_OCW2,
+                                I8259A_OCW2_SL  |
+                                I8259A_OCW2_EOI |
+                                irqNo               );
+        
+        /* PIC2(スレーブ)EOI通知 */
+        IA32InstructionOutByte( I8259A_M_PORT_OCW2,
+                                I8259A_OCW2_SL  |
+                                I8259A_OCW2_EOI |
+                                I8259A_IRQ2         );
+    }
+    
+    /* デバッグトレースログ出力 *//*
+    DEBUG_LOG( "%s() end.", __func__ );*/
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/IntMng/IntMngPic.h b/src/booter/IntMng/IntMngPic.h
new file mode 100644 (file)
index 0000000..cf6a58d
--- /dev/null
@@ -0,0 +1,16 @@
+/******************************************************************************/
+/* src/booter/IntMng/IntMngPic.h                                              */
+/*                                                                 2017/06/20 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef INTMNG_PIC_H
+#define INTMNG_PIC_H
+/******************************************************************************/
+/* グローバル関数宣言                                                         */
+/******************************************************************************/
+/* PIC管理初期化 */
+extern void IntMngPicInit( void );
+
+
+/******************************************************************************/
+#endif
index c6ec5c8..d6308aa 100644 (file)
@@ -1,7 +1,7 @@
 /******************************************************************************/
 /* src/booter/Ipl/IplMain.s                                                   */
-/*                                                                 2016/12/04 */
-/* Copyright (C) 2016 Mochi.                                                  */
+/*                                                                 2017/06/18 */
+/* Copyright (C) 2016-2017 Mochi.                                             */
 /******************************************************************************/
 .intel_syntax noprefix
 .code16
@@ -38,30 +38,34 @@ migrate:
     mov         ds, ax
     
     /* メインプログラム格納位置取得 */
-    mov         eax, [ pt1_start_lba ]
-    mov         [ pReadAddr ], eax
+    mov         eax, [ pt1StartLBA ]
+    mov         [ dapReadAddr ], eax
+    mov         ax, [ pt1Size ]
+    mov         [ dapReadSize ], ax
     
     /* メインプログラム読み込み */
-    mov         ah, 0x42                    /* 機能番号(EXTENDED READ)   */
-    mov         dl, 0x80                    /* ドライブ番号                */
-    mov         si, offset pDiskAddrPckt    /* Disk address packetアドレス */
+    mov         ah, 0x42        /* 機能番号(EXTENDED READ)   */
+    mov         dl, 0x80        /* ドライブ番号                */
+    mov         si, offset dap  /* Disk address packetアドレス */
     int         0x13
     
     /* メインプログラム実行 */
     jmp         0x0000:0x7C00
     
 .align 8
-/* Disk address packet */
-pDiskAddrPckt:
+/* Disk Address Packet */
+dap:
     .byte       0x10            /* サイズ                          */
     .byte       0x00            /* Reserved                        */
-    .word       0x0010          /* 読込み論理セクタ数              */
+dapReadSize:
+    .word       0x0000          /* 読込み論理セクタ数              */
     .word       0x0000          /* 転送先アドレス(オフセット)    */
     .word       0x07C0          /* 転送先アドレス(セグメント)    */
-pReadAddr:
+dapReadAddr:
     .long       0x00000000      /* 読込み先頭論理セクタ番号(LSB) */
     .long       0x00000000      /* 読込み先頭論理セクタ番号(MSB) */
 
+
 /******************************************************************************/
 /* パーティションテーブル                                                     */
 /******************************************************************************/
@@ -71,10 +75,10 @@ pReadAddr:
     .byte       0x00, 0x00, 0x00    /* パーティション先頭位置(CHS方式) */
     .byte       0x00                /* パーティション種別                */
     .byte       0x00, 0x00, 0x00    /* パーティション末尾位置(CHS方式) */
-pt1_start_lba:
+pt1StartLBA:
     .long       0x00000000          /* パーティション先頭位置(LBA方式) */
-pt1_size:
-    .long       0x00000000          /* パーティションサイズ              */
+pt1Size:
+    .long       0x00000000          /* パーティションサイズ(セクタ)    */
 
 
 /******************************************************************************/
diff --git a/src/booter/LoadMng/LoadMngInit.c b/src/booter/LoadMng/LoadMngInit.c
new file mode 100644 (file)
index 0000000..182171c
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************************/
+/* src/booter/LoadMng/LoadMngInit.c                                           */
+/*                                                                 2017/07/05 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+#include <stdint.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <Driver.h>
+
+/* 内部モジュールヘッダ */
+#include "LoadMngInit.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                     \
+    DebugLogOutput( CMN_MODULE_LOADMNG_INIT, \
+                    __LINE__,                \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+/** MBR */
+typedef struct {
+    uint8_t code[ 446 ];        /**< ブートストラップコード */
+    pt_t    partitionTbl[ 4 ];  /**< パーティションテーブル */
+    uint8_t signature[ 2 ];     /**< ブートシグネチャ       */
+} __attribute__( ( packed ) ) mbr_t;
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/** パーティションテーブル */
+pt_t gLoadMngInitPt[ 4 ];
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       ロード管理初期化
+ * @details     ロード管理モジュールを初期化する。
+ */
+/******************************************************************************/
+void LoadMngInit( void )
+{
+    mbr_t mbr;  /* MBR */
+    
+    /* トレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* MBR読込み */
+    DriverAtaRead( &mbr, 0, 1 );
+    
+    /* パーティションテーブル取得 */
+    gLoadMngInitPt[ 0 ] = mbr.partitionTbl[ 0 ];
+    gLoadMngInitPt[ 1 ] = mbr.partitionTbl[ 1 ];
+    gLoadMngInitPt[ 2 ] = mbr.partitionTbl[ 2 ];
+    gLoadMngInitPt[ 3 ] = mbr.partitionTbl[ 3 ];
+    
+    /* トレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/LoadMng/LoadMngInit.h b/src/booter/LoadMng/LoadMngInit.h
new file mode 100644 (file)
index 0000000..08f678d
--- /dev/null
@@ -0,0 +1,50 @@
+/******************************************************************************/
+/* src/booter/LoadMng/LoadMngInit.h                                           */
+/*                                                                 2017/07/03 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef LOADMNG_INIT_H
+#define LOADMNG_INIT_H
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdint.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/** CYLINDER取得マクロ */
+#define GET_CYLINDER( _CYLSEC )     \
+    ( ( ( _CYLSEC >> 6 ) & 0x0300 ) | ( _CYLSEC & 0x00FF ) )
+
+/** SECTOR取得マクロ */
+#define GET_SECTOR( _CYLSEC ) ( ( _CYLSEC >> 8 ) & 0x3F )
+
+/** CHSアドレス */
+typedef struct {
+    uint16_t cylSec;            /**< シリンダ&セクタ */
+    uint8_t  head;              /**< ヘッド          */
+}  __attribute__( ( packed ) ) chs_t;
+
+/** パーティションテーブル */
+typedef struct {
+    uint8_t  status;            /**< ステータス           */
+    chs_t    chsFirstAddr;      /**< CHS先頭アドレス      */
+    uint8_t  type;              /**< パーティションタイプ */
+    chs_t    chsLastAddr;       /**< CHS最後尾アドレス    */
+    uint32_t lbaFirstAddr;      /**< LBA先頭アドレス      */
+    uint32_t lbaSize;           /**< LBAサイズ            */
+} __attribute__( ( packed ) ) pt_t;
+
+
+/******************************************************************************/
+/* 変数定義                                                                   */
+/******************************************************************************/
+/** パーティションテーブル */
+extern pt_t gLoadMngInitPt[ 4 ];
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/LoadMng/LoadMngKernel.c b/src/booter/LoadMng/LoadMngKernel.c
new file mode 100644 (file)
index 0000000..48f75d1
--- /dev/null
@@ -0,0 +1,63 @@
+/******************************************************************************/
+/* src/booter/LoadMng/LoadMngKernel.c                                         */
+/*                                                                 2017/07/11 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdarg.h>
+#include <kernel/MochiKernel.h>
+
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+#include <Debug.h>
+#include <Driver.h>
+#include <LoadMng.h>
+
+/* 内部モジュールヘッダ */
+#include "LoadMngInit.h"
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* デバッグトレースログ出力マクロ */
+#ifdef DEBUG_LOG_ENABLE
+#define DEBUG_LOG( ... )                       \
+    DebugLogOutput( CMN_MODULE_LOADMNG_KERNEL, \
+                    __LINE__,                  \
+                    __VA_ARGS__ )
+#else
+#define DEBUG_LOG( ... )
+#endif
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       カーネル読込み
+ * @details     カーネルを読み込む
+ */
+/******************************************************************************/
+void LoadMngKernelLoad( void )
+{
+    /* トレースログ出力 */
+    DEBUG_LOG( "%s() start.", __func__ );
+    
+    /* カーネル読込み */
+    DriverAtaRead( ( void * ) MOCHIKERNEL_ADDR_ENTRY,
+                   gLoadMngInitPt[ 1 ].lbaFirstAddr,
+                   gLoadMngInitPt[ 1 ].lbaSize );
+    
+    /* トレースログ出力 */
+    DEBUG_LOG( "%s() end.", __func__ );
+    
+    return;
+}
+
+
+/******************************************************************************/
diff --git a/src/booter/Loader/LoaderLoad.s b/src/booter/Loader/LoaderLoad.s
deleted file mode 100644 (file)
index 923350c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************/
-/* src/booter/Loader/LoaderLoad.s                                             */
-/*                                                                 2016/12/04 */
-/* Copyright (C) 2016 Mochi.                                                  */
-/******************************************************************************/
-.intel_syntax noprefix
-.code16
-/******************************************************************************/
-/* グローバル宣言                                                             */
-/******************************************************************************/
-.global LoaderLoadKernel
-
-
-/******************************************************************************/
-/* TEXTセクション                                                             */
-/******************************************************************************/
-.section .text
-LoaderLoadKernel:
-    /* カーネル格納位置取得 */
-    xor         ax, ax
-    mov         ds, ax
-    mov         eax, [ 0x7A00 + 0x1CE + 0x8 ]
-    mov         [ pReadAddr ], eax
-    
-    /* メインプログラム読み込み */
-    mov         ah, 0x42                    /* 機能番号(EXTENDED READ)   */
-    mov         dl, 0x80                    /* ドライブ番号                */
-    mov         si, offset pDiskAddrPckt    /* Disk address packetアドレス */
-    int         0x13
-    
-    ret
-    
-
-/******************************************************************************/
-/* DATAセクション                                                             */
-/******************************************************************************/
-.section .data
-.align 8
-/* Disk address packet */
-pDiskAddrPckt:
-    .byte       0x10            /* サイズ                          */
-    .byte       0x00            /* Reserved                        */
-    .word       0x0070          /* 読込み論理セクタ数              */
-    .word       0x0010          /* 転送先アドレス(オフセット)    */
-    .word       0xFFFF          /* 転送先アドレス(セグメント)    */
-pReadAddr:
-    .long       0x00000000      /* 読込み先頭論理セクタ番号(LSB) */
-    .long       0x00000000      /* 読込み先頭論理セクタ番号(MSB) */
-
-
-/******************************************************************************/
index 1f553c2..7238069 100644 (file)
@@ -1,7 +1,7 @@
 #******************************************************************************#
 #* src/booter/Makefile                                                        *#
-#*                                                                 2016/12/04 *#
-#* Copyright (C) 2016 Mochi.                                                  *#
+#*                                                                 2017/07/06 *#
+#* Copyright (C) 2016-2017 Mochi.                                             *#
 #******************************************************************************#
 #******************************************************************************#
 #* マクロ設定                                                                 *#
@@ -17,16 +17,36 @@ MAIN_NAME = booter-main
 # IPL部ソースコード
 IPL_SRCS  = Ipl/IplMain.s
 # メイン部ソースコード
-MAIN_SRCS = Initctrl/InitctrlMain.s \
-            Initctrl/InitctrlA20.s  \
-            Initctrl/InitctrlCpu.s  \
-            Loader/LoaderLoad.s
+MAIN_SRCS = InitCtrl/InitCtrlInit16.s \
+            InitCtrl/InitCtrlInit32.s \
+            IntMng/IntMngInit.c       \
+            IntMng/IntMngIdt.c        \
+            IntMng/IntMngHdl.c        \
+            IntMng/IntMngPic.c        \
+            Driver/DriverInit.c       \
+            Driver/DriverA20.c        \
+            Driver/DriverAta.c        \
+            LoadMng/LoadMngInit.c     \
+            LoadMng/LoadMngKernel.c   \
+            Debug/DebugInit.c         \
+            Debug/DebugLog.c
 
 # ASフラグ
-ASFLAGS = -32
+ASFLAGS = --32
+
+# Cフラグ
+CFLAGS = -O                 \
+         -Wall              \
+         -masm=intel        \
+         -m32               \
+         -ffreestanding     \
+         -Iinclude/         \
+         -I../include       \
+         -DDEBUG_LOG_ENABLE
 
 # LDフラグ
-LDFLAGS = -melf_i386
+LDFLAGS = -melf_i386 \
+          -lc
 
 
 #******************************************************************************#
@@ -42,7 +62,12 @@ DIR_LIST  = $(sort $(addprefix $(OBJS_DIR)/, $(dir $(IPL_SRCS) $(MAIN_SRCS))))
 # IPL部オブジェクトファイル
 IPL_OBJS  = $(addprefix $(OBJS_DIR)/, $(IPL_SRCS:.s=.o))
 # メイン部オブジェクトファイル
-MAIN_OBJS = $(addprefix $(OBJS_DIR)/, $(MAIN_SRCS:.s=.o))
+MAIN_OBJS = $(addprefix $(OBJS_DIR)/,                           \
+              $(patsubst %.s,%.o,$(filter %.s, $(MAIN_SRCS)))   \
+              $(patsubst %.c,%.o,$(filter %.c, $(MAIN_SRCS))))
+
+# ライブラリディレクトリ
+LDFLAGS += -L$(BASE_DIR)/build/objs/libraries
 
 
 #******************************************************************************#
index 9c891ed..e07980f 100644 (file)
@@ -1,15 +1,17 @@
 /******************************************************************************/
 /* src/booter/booter-main.lds                                                 */
-/*                                                                 2016/12/04 */
-/* Copyright (C) 2016 Mochi.                                                  */
+/*                                                                 2017/06/28 */
+/* Copyright (C) 2016-2017 Mochi.                                             */
 /******************************************************************************/
 OUTPUT_FORMAT( binary )
-ENTRY( InitctrlMain )
+ENTRY( InitCtrlInit16 )
 
 SECTIONS {
     . = 0x7C00;
-    .text : { * ( .text ) }
-    .data : { * ( .data ) }
+    .text   : { * ( .text   ) }
+    .rodata : { * ( .rodata ) }
+    .data   : { * ( .data   ) }
+    .bss    : { * ( .bss    ) }
 }
 
 
diff --git a/src/booter/include/Cmn.h b/src/booter/include/Cmn.h
new file mode 100644 (file)
index 0000000..7a1c886
--- /dev/null
@@ -0,0 +1,67 @@
+/******************************************************************************/
+/* src/booter/include/Cmn.h                                                   */
+/*                                                                 2017/07/04 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef CMN_H
+#define CMN_H
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 共通ヘッダ */
+#include <stdbool.h>
+#include <stdint.h>
+#include <hardware/IA32/IA32Instruction.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* 処理結果 */
+#define CMN_SUCCESS             (  0 )      /** 成功 */
+#define CMN_FAILURE             ( -1 )      /** 失敗 */
+
+/* モジュール・サブモジュール識別子 */
+#define CMN_MODULE_INIT_INIT      ( 0x0101 )  /** 初期化制御(初期化)     */
+#define CMN_MODULE_INTMNG_INIT    ( 0x0201 )  /** 割込管理(初期化)       */
+#define CMN_MODULE_INTMNG_PIC     ( 0x0202 )  /** 割込管理(PIC管理)      */
+#define CMN_MODULE_INTMNG_IDT     ( 0x0203 )  /** 割込管理(IDT管理)      */
+#define CMN_MODULE_INTMNG_HDL     ( 0x0204 )  /** 割込管理(ハンドラ管理) */
+#define CMN_MODULE_DRIVER_INIT    ( 0x0301 )  /** ドライバ(初期化)       */
+#define CMN_MODULE_DRIVER_A20     ( 0x0302 )  /** ドライバ(A20)          */
+#define CMN_MODULE_DRIVER_ATA     ( 0x0303 )  /** ドライバ(ATA)          */
+#define CMN_MODULE_LOADMNG_INIT   ( 0x0401 )  /** 読込管理(初期化)       */
+#define CMN_MODULE_LOADMNG_KERNEL ( 0x0402 )  /** 読込管理(カーネル)     */
+#define CMN_MODULE_DEBUG_INIT     ( 0x0401 )  /** デバッグ制御(初期化)   */
+#define CMN_MODULE_DEBUG_LOG      ( 0x0402 )  /** デバッグ制御(ログ管理) */
+
+/** モジュール・サブモジュール数 */
+#define CMN_MODULE_NUM          ( 12 )
+
+/** 処理結果構造体 */
+typedef int32_t CmnRet_t;
+
+
+/******************************************************************************/
+/* インライン関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       アボート
+ * @details     無限ループする。
+ */
+/******************************************************************************/
+static inline void CmnAbort( void )
+{
+    /* 割込み禁止 */
+    IA32InstructionCli();
+    
+    /* 無限ループ */
+    while ( true ) {
+        IA32InstructionHlt();
+    }
+}
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/include/Debug.h b/src/booter/include/Debug.h
new file mode 100644 (file)
index 0000000..e0b75a1
--- /dev/null
@@ -0,0 +1,35 @@
+/******************************************************************************/
+/* src/booter/include/Debug.h                                                 */
+/*                                                                 2017/06/26 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef DEBUG_H
+#define DEBUG_H
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+#include <stdarg.h>
+#include <stdint.h>
+
+
+/******************************************************************************/
+/* グローバル関数プロトタイプ宣言                                             */
+/******************************************************************************/
+/*-------------*/
+/* DebugInit.c */
+/*-------------*/
+/* デバッグ制御初期化 */
+extern void DebugInit( void );
+
+/*------------*/
+/* DebugLog.c */
+/*------------*/
+/* トレースログ出力 */
+extern void DebugLogOutput( uint32_t moduleId,
+                            uint32_t lineNum,
+                            char     *format,
+                            ...                );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/include/Driver.h b/src/booter/include/Driver.h
new file mode 100644 (file)
index 0000000..1639e58
--- /dev/null
@@ -0,0 +1,45 @@
+/******************************************************************************/
+/* src/booter/include/Driver.h                                                */
+/*                                                                 2017/06/26 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef DRIVER_H
+#define DRIVER_H
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+/* 外部モジュールヘッダ */
+#include <Cmn.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/*--------------*
+ * DriverInit.c *
+ *--------------*/
+/* ドライバ初期化 */
+void DriverInit( void );
+
+
+/*-------------*
+ * DriverA20.c *
+ *-------------*/
+/* A20ライン有効化 */
+CmnRet_t DriverA20Enable( void );
+
+
+/*-------------*
+ * DriverAta.c *
+ *-------------*/
+/* ATA割込みハンドラ */
+void DriverAtaHandler( uint32_t intNo );
+
+/* ディスク読み込み */
+CmnRet_t DriverAtaRead( void     *pAddr,
+                        uint32_t lba,
+                        size_t   size    );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/include/IntMng.h b/src/booter/include/IntMng.h
new file mode 100644 (file)
index 0000000..9518b72
--- /dev/null
@@ -0,0 +1,59 @@
+/******************************************************************************/
+/* src/booter/include/IntMng.h                                                */
+/*                                                                 2017/06/20 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef INTMNG_H
+#define INTMNG_H
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* 割込み番号定義 */
+#define INTMNG_INT_NO_MIN    (    0 )                   /** 割込み番号最小値 */
+#define INTMNG_INT_NO_MAX    ( 0x2F )                   /** 割込み番号最大値 */
+#define INTMNG_INT_NO_NUM    ( INTMNG_INT_NO_MAX + 1 )  /** 割込み番号数     */
+
+/** PICベクタ番号ベース */
+#define INTMNG_PIC_VCTR_BASE ( 0x20 )
+
+/** 割込みハンドラ関数型 */
+typedef void ( *IntMngHdl_t )( uint32_t intNo );
+
+
+/******************************************************************************/
+/* グローバル関数プロトタイプ宣言                                             */
+/******************************************************************************/
+/*--------------*/
+/* IntMngInit.c */
+/*--------------*/
+/* 割込み管理初期化 */
+extern void IntMngInit( void );
+
+/*-------------*/
+/* IntMngHdl.c */
+/*-------------*/
+/* 割込みハンドラ設定 */
+extern void IntMngHdlSet( uint32_t    intNo,
+                          IntMngHdl_t func   );
+
+/*-------------*/
+/* IntMngPic.c */
+/*-------------*/
+/* PIC割込み許可 */
+extern void IntMngPicAllowIrq( uint8_t irqNo );
+
+/* PIC割込み拒否 */
+extern void IntMngPicDenyIrq( uint8_t irqNo );
+
+/* PIC割込み無効化 */
+extern void IntMngPicDisable( void );
+
+/* PIC割込み有効化 */
+extern void IntMngPicEnable( void );
+
+/* PIC割込みEOI通知 */
+extern void IntMngPicEoi( uint8_t irqNo );
+
+
+/******************************************************************************/
+#endif
diff --git a/src/booter/include/LoadMng.h b/src/booter/include/LoadMng.h
new file mode 100644 (file)
index 0000000..afe74ed
--- /dev/null
@@ -0,0 +1,26 @@
+/******************************************************************************/
+/* src/booter/include/LoadMng.h                                               */
+/*                                                                 2017/07/11 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef LOADMNG_H
+#define LOADMNG_H
+/******************************************************************************/
+/* グローバル関数プロトタイプ宣言                                             */
+/******************************************************************************/
+/*---------------*
+ * LoadMngInit.c *
+ *---------------*/
+/* ロード管理初期化 */
+extern void LoadMngInit( void );
+
+
+/*-----------------*
+ * LoadMngKernel.c *
+ *-----------------*/
+/* カーネル読込み */
+extern void LoadMngKernelLoad( void );
+
+
+/******************************************************************************/
+#endif
index 1742fc1..8a0673b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/include/MLib/Basic/MLibBasic.h                                         */
-/*                                                                 2017/06/16 */
+/*                                                                 2017/06/22 */
 /* Copyright (C) 2017 Mochi                                                   */
 /******************************************************************************/
 #ifndef _MLIB_BASIC_H_
@@ -13,7 +13,7 @@
     ( ( ( _VALUE ) + ( ( _ALIGNMENT ) - 1 ) ) & ~( ( _ALIGNMENT ) - 1 ) )
 
 /** フラグ判定マクロ */
-#define MLIB_BASIC_IS_FLAG( _VALUE, _FLAG )     \
+#define MLIB_BASIC_HAVE_FLAG( _VALUE, _FLAG )   \
     ( ( ( _VALUE ) & ( _FLAG ) ) == ( _FLAG ) )
 
 
diff --git a/src/include/hardware/ATA/ATA.h b/src/include/hardware/ATA/ATA.h
new file mode 100644 (file)
index 0000000..1fe9a84
--- /dev/null
@@ -0,0 +1,77 @@
+/******************************************************************************/
+/* src/include/hardware/ATA/ATA.h                                             */
+/*                                                                 2017/06/25 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+#ifndef ATA_H
+#define ATA_H
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* PITポート定義 */
+#define ATA_PORT_DATA       ( 0x01F0 )  /** Data レジスタ             */
+#define ATA_PORT_ERROR      ( 0x01F1 )  /** Error レジスタ            */
+#define ATA_PORT_FEATURES   ( 0x01F1 )  /** Features レジスタ         */
+#define ATA_PORT_SECTOR_CNT ( 0x01F2 )  /** Sector Count レジスタ     */
+#define ATA_PORT_SECTOR_NUM ( 0x01F3 )  /** Sector Number レジスタ    */
+#define ATA_PORT_CYL_LOW    ( 0x01F4 )  /** Cylinder Low レジスタ     */
+#define ATA_PORT_CYL_HIGH   ( 0x01F5 )  /** Cylinder High レジスタ    */
+#define ATA_PORT_DEV_HEAD   ( 0x01F6 )  /** Device/Head レジスタ      */
+#define ATA_PORT_STATUS     ( 0x01F7 )  /** Status レジスタ           */
+#define ATA_PORT_COMMAND    ( 0x01F7 )  /** Command レジスタ          */
+#define ATA_PORT_ALT_STATUS ( 0x03F6 )  /** Alternate Status レジスタ */
+#define ATA_PORT_DEV_CTRL   ( 0x03F6 )  /** Device Control レジスタ   */
+
+/* Status / Alternate Status レジスタビット定義 */
+#define ATA_STATUS_BSY      ( 0x80 )    /** ビジー               */
+#define ATA_STATUS_DRDY     ( 0x40 )    /** デバイスレディ       */
+#define ATA_STATUS_DF       ( 0x20 )    /** デバイス障害         */
+#define ATA_STATUS_DSC      ( 0x10 )    /** デバイスシーク完了   */
+#define ATA_STATUS_DRQ      ( 0x08 )    /** データ転送要求       */
+#define ATA_STATUS_CORR     ( 0x04 )    /** 修正可能データエラー */
+#define ATA_STATUS_IDX      ( 0x02 )    /** Index(ベンダ特有)  */
+#define ATA_STATUS_ERR      ( 0x01 )    /** エラー発生           */
+
+/* Error レジスタビット定義 */
+#define ATA_ERROR_UNC       ( 0x40 )    /** 修正不可能データエラー */
+#define ATA_ERROR_MC        ( 0x20 )    /** メディア交換           */
+#define ATA_ERROR_IDNF      ( 0x10 )    /** セクタID不検知         */
+#define ATA_ERROR_MCR       ( 0x08 )    /** メディア交換要求       */
+#define ATA_ERROR_ABRT      ( 0x04 )    /** コマンドアボート       */
+#define ATA_ERROR_TK0NF     ( 0x02 )    /** Track0不検知           */
+#define ATA_ERROR_AMNF      ( 0x01 )    /** アドレスマーク不検知   */
+
+/* Device/Head レジスタビット定義 */
+#define ATA_DEV_HEAD_LBA    ( 0x40 )    /** LBA/CHSモード    */
+#define ATA_DEV_HEAD_DEV    ( 0x10 )    /** デバイスアドレス */
+#define ATA_DEV_HEAD_HS3    ( 0x08 )    /** ヘッド番号       */
+#define ATA_DEV_HEAD_HS2    ( 0x04 )    /** ヘッド番号       */
+#define ATA_DEV_HEAD_HS1    ( 0x02 )    /** ヘッド番号       */
+#define ATA_DEV_HEAD_HS0    ( 0x01 )    /** ヘッド番号       */
+#define ATA_DEV_HEAD_LBA4   ( 0x0F )    /** LBA[27:24]       */
+
+/* Device Control レジスタビット定義 */
+#define ATA_DEV_CTRL_SRST   ( 0x04 )    /** ソフトウェアリセット */
+#define ATA_DEV_CTRL_NIEN   ( 0x02 )    /** デバイス割込み許可   */
+
+/* Sector Count レジスタ定義 */
+#define ATA_SECTOR_CNT_MAX  ( 256 )     /** セクタカウント最大値 */
+
+/* Data レジスタ定義 */
+#define ATA_TRANSFER_COUNT  ( 256 )     /** データ転送回数 */
+
+/* コマンド */
+#define ATA_CMD_READ_SECTOR ( 0x20 )    /** READ SECTOR(S)コマンド */
+
+/** LBA->SectorNumberレジスタ変換マクロ */
+#define ATA_LBA_TO_SECTOR_NUM( _LBA ) ( (   _LBA         ) & 0xFF )
+/** LBA->CylinderLowレジスタ変換マクロ */
+#define ATA_LBA_TO_CYL_LOW( _LBA )    ( ( ( _LBA ) >>  8 ) & 0xFF )
+/** LBA->CylinderHighレジスタ変換マクロ */
+#define ATA_LBA_TO_CYL_HIGH( _LBA )   ( ( ( _LBA ) >> 16 ) & 0xFF )
+/** LBA->Device/Headレジスタ変換マクロ */
+#define ATA_LBA_TO_DEV_HEAD( _LBA )   ( ( ( _LBA ) >> 24 ) & 0x0F )
+
+
+/******************************************************************************/
+#endif
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/kernel/include/hardware/IA32/IA32Instruction.h                         */
-/*                                                                 2017/06/16 */
+/*                                                                 2017/07/07 */
 /* Copyright (C) 2016-2017 Mochi.                                             */
 /******************************************************************************/
 #ifndef IA32_INSTRUCTION_H
@@ -8,6 +8,7 @@
 /******************************************************************************/
 /* インクルード                                                               */
 /******************************************************************************/
+#include <stddef.h>
 #include <stdint.h>
 #include "IA32Descriptor.h"
 #include "IA32Paging.h"
@@ -603,6 +604,38 @@ static inline void IA32InstructionPushGs( void )
 
 /******************************************************************************/
 /**
+ * @brief       rep insw命令実行
+ * @details     rep insw命令を実行して、指定I/Oポートから16bitの値を読み込み、
+ *              指定アドレスに格納する処理をアドレスを進めながら指定回数分繰り
+ *              返す。
+ * 
+ * @param[out]  *pAddr 格納先アドレス
+ * @param[in]   port   I/Oポート番号
+ * @param[in]   count  繰り返し回数
+ */
+/******************************************************************************/
+static inline void IA32InstructionRepInsw( void     *pAddr,
+                                           uint16_t port,
+                                           size_t   count   )
+{
+    /* insw命令実行 */
+    __asm__ __volatile__ ( "mov edi, %0;"   /* edi 格納先アドレス設定 */
+                           "cld;"           /* 増加設定               */
+                           "rep insw"       /* insw命令実行           */
+                           :                /* 出力無し               */
+                           : "m" ( pAddr ), /* edi 格納先アドレス     */
+                             "d" ( port  ), /* dx  I/Oポート番号設定  */
+                             "c" ( count )  /* ecx 繰り返し回数設定   */
+                           : "edi",         /* ediレジスタ破壊指定    */
+                             //"cx",         /* ecxレジスタ破壊指定    */
+                             "cc" );        /* EFLAGSレジスタ破壊指定 */
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
  * @brief       cr0レジスタ設定
  * @details     cr0レジスタにシステム制御フラグを設定する。
  * 
@@ -770,4 +803,19 @@ static inline void IA32InstructionSwitchTask( IA32PagingPDBR_t pdbr,
 
 
 /******************************************************************************/
+/**
+ * @brief       wbinvd命令実行
+ * @details     キャッシュをメモリにライトバックし、キャッシュを無効化する。
+ */
+/******************************************************************************/
+static inline void IA32InstructionWbinvd( void )
+{
+    /* wbinvd命令実行 */
+    __asm__ __volatile__ ( "wbinvd" );
+    
+    return;
+}
+
+
+/******************************************************************************/
 #endif
index 4bf60f7..45d5ce9 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/include/kernel/MochiKernel.h                                           */
-/*                                                                 2017/05/24 */
+/*                                                                 2017/07/11 */
 /* Copyright (C) 2017 Mochi                                                   */
 /******************************************************************************/
 #ifndef _MOCHI_KERNEL_H_
 /******************************************************************************/
 /* 定義                                                                       */
 /******************************************************************************/
+/* カーネル位置 */
+#define MOCHIKERNEL_ADDR_ENTRY ( 0x00100000 )   /** エントリポイント */
+#define MOCHIKERNEL_ADDR_STACK ( 0x04000000 )   /** スタックアドレス */
+
 /* メモリ領域タイプ */
 #define MOCHIKERNEL_MEMORY_TYPE_AVAILABLE ( 0x01 )  /** 使用可能メモリ領域 */
 #define MOCHIKERNEL_MEMORY_TYPE_RESERVED  ( 0x02 )  /** 使用不可メモリ領域 */
index 65b408c..7459313 100644 (file)
@@ -1,6 +1,6 @@
 #******************************************************************************#
 #* src/kernel/Makefile                                                        *#
-#*                                                                 2017/06/01 *#
+#*                                                                 2017/07/06 *#
 #* Copyright (C) 2016-2017 Mochi.                                             *#
 #******************************************************************************#
 #******************************************************************************#
index 8e41e8d..59dbe7b 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/kernel/ProcMng/ProcMngElf.c                                            */
-/*                                                                 2017/06/13 */
+/*                                                                 2017/06/22 */
 /* Copyright (C) 2017 Mochi.                                                  */
 /******************************************************************************/
 /******************************************************************************/
@@ -155,7 +155,7 @@ CmnRet_t ProcMngElfLoad( void             *pAddr,
             pEntry->p_filesz );
         
         /* フラグ判定 */
-        if ( MLIB_BASIC_IS_FLAG( pEntry->p_flags, PF_R | PF_W ) ) {
+        if ( MLIB_BASIC_HAVE_FLAG( pEntry->p_flags, PF_R | PF_W ) ) {
             /* 読書可能セグメント */
             
             attrRw = IA32_PAGING_RW_RW;
@@ -459,9 +459,9 @@ static CmnRet_t ElfCheckPrgHeader( void   *pAddr,
         }
         
         /* フラグチェック */
-        if ( !( MLIB_BASIC_IS_FLAG( pEntry->p_flags, PF_X ) ||
-                MLIB_BASIC_IS_FLAG( pEntry->p_flags, PF_W ) ||
-                MLIB_BASIC_IS_FLAG( pEntry->p_flags, PF_R )    ) ) {
+        if ( !( MLIB_BASIC_HAVE_FLAG( pEntry->p_flags, PF_X ) ||
+                MLIB_BASIC_HAVE_FLAG( pEntry->p_flags, PF_W ) ||
+                MLIB_BASIC_HAVE_FLAG( pEntry->p_flags, PF_R )    ) ) {
             /* 不正値 */
             
             /* デバッグトレースログ出力 */
index 24ac4e9..ce5c466 100644 (file)
@@ -1,17 +1,28 @@
 #******************************************************************************#
 #* src/libraries/Makefile                                                     *#
-#*                                                                 2017/02/04 *#
+#*                                                                 2017/06/18 *#
 #* Copyright (C) 2016-2017 Mochi.                                             *#
 #******************************************************************************#
 #******************************************************************************#
 #* マクロ設定                                                                 *#
 #******************************************************************************#
+# ベースディレクトリsrc/からの相対パス
+CUR_DIR  = libraries
+
 # サブディレクトリ
 SUB_DIRS = libc \
            libMLibBasic
 
 
 #******************************************************************************#
+#* 自動設定マクロ                                                             *#
+#******************************************************************************#
+# ベースディレクトリパス
+BASE_DIR  = $(shell pwd | sed -e 's/\/src\/$(subst /,\/,$(CUR_DIR))//')
+# 中間ファイル格納先ディレクトリパス
+OBJS_DIR  = $(BASE_DIR)/build/objs/$(CUR_DIR)
+
+#******************************************************************************#
 #* phonyターゲット                                                            *#
 #******************************************************************************#
 # サブディレクトリも含めたコンパイル
@@ -33,6 +44,7 @@ ifdef SUB_DIRS
            $(MAKE) -C $$subdir clean; \
        done
 endif
+       -rm -rf $(OBJS_DIR)
 
 
 #******************************************************************************#
diff --git a/src/tools/Makefile b/src/tools/Makefile
new file mode 100644 (file)
index 0000000..c73f847
--- /dev/null
@@ -0,0 +1,49 @@
+#******************************************************************************#
+#* src/tools/Makefile                                                         *#
+#*                                                                 2017/06/29 *#
+#* Copyright (C) 2017 Mochi.                                                  *#
+#******************************************************************************#
+#******************************************************************************#
+#* マクロ設定                                                                 *#
+#******************************************************************************#
+# ベースディレクトリsrc/からの相対パス
+CUR_DIR  = tools
+
+# サブディレクトリ
+SUB_DIRS = makedisk
+
+
+#******************************************************************************#
+#* 自動設定マクロ                                                             *#
+#******************************************************************************#
+# ベースディレクトリパス
+BASE_DIR  = $(shell pwd | sed -e 's/\/src\/$(subst /,\/,$(CUR_DIR))//')
+# 生成ファイル格納先ディレクトリパス
+TOOLS_DIR  = $(BASE_DIR)/build/tools
+
+#******************************************************************************#
+#* phonyターゲット                                                            *#
+#******************************************************************************#
+# サブディレクトリも含めたコンパイル
+.PHONY: all
+all:
+ifdef SUB_DIRS
+       @for subdir in $(SUB_DIRS); \
+       do \
+           $(MAKE) -C $$subdir all; \
+       done
+endif
+
+# 全生成ファイルの削除
+.PHONY: clean
+clean:
+ifdef SUB_DIRS
+       @for subdir in $(SUB_DIRS); \
+       do \
+           $(MAKE) -C $$subdir clean; \
+       done
+endif
+       -rm -rf $(TOOLS_DIR)
+
+
+#******************************************************************************#
diff --git a/src/tools/makedisk/Makefile b/src/tools/makedisk/Makefile
new file mode 100644 (file)
index 0000000..08a3c4b
--- /dev/null
@@ -0,0 +1,56 @@
+#******************************************************************************#
+#* src/tools/makedisk/Makefile                                                *#
+#*                                                                 2017/06/29 *#
+#* Copyright (C) 2017 Mochi.                                                  *#
+#******************************************************************************#
+#******************************************************************************#
+#* マクロ設定                                                                 *#
+#******************************************************************************#
+# ベースディレクトリsrc/からの相対パス
+CUR_DIR   = tools/makedisk
+
+# バイナリ名
+TOOL_NAME = makedisk
+
+# ソースコード
+SRCS      = makedisk.c
+
+# Cフラグ
+CFLAGS    = 
+
+
+#******************************************************************************#
+#* 自動設定マクロ                                                             *#
+#******************************************************************************#
+# ベースディレクトリパス
+BASE_DIR  = $(shell pwd | sed -e 's/\/src\/$(subst /,\/,$(CUR_DIR))//')
+# 生成ファイル格納先ディレクトリパス
+TOOLS_DIR  = $(BASE_DIR)/build/tools
+
+
+#******************************************************************************#
+#* phonyターゲット                                                            *#
+#******************************************************************************#
+# サブディレクトリも含めたコンパイル
+.PHONY: all
+all: $(TOOLS_DIR) $(TOOLS_DIR)/$(TOOL_NAME) Makefile
+
+# 全生成ファイルの削除
+.PHONY: clean
+clean:
+       -rm -rf $(TOOLS_DIR)/$(TOOL_NAME)
+
+
+#******************************************************************************#
+#* 生成規則                                                                   *#
+#******************************************************************************#
+# ディレクトリ
+$(TOOLS_DIR):
+       mkdir -p $@
+
+# バイナリ
+$(TOOLS_DIR)/$(TOOL_NAME): $(SRCS) Makefile
+       $(CC) $(CFLAGS) -o $@ $(SRCS)
+
+
+#******************************************************************************#
diff --git a/src/tools/makedisk/makedisk.c b/src/tools/makedisk/makedisk.c
new file mode 100644 (file)
index 0000000..9d758fd
--- /dev/null
@@ -0,0 +1,873 @@
+/******************************************************************************/
+/* src/tools/makedisk/makedisk.c                                              */
+/*                                                                 2017/07/02 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/* パーティションテーブル定義 */
+#define PT_STATUS_BOOT          ( 0x80 )    /** ブート可能 */
+#define PT_TYPE_MOCHI_BOOTER    ( 0x30 )    /** MochiBooter用パーティション */
+#define PT_TYPE_MOCHI_KERNEL    ( 0x31 )    /** MochiKernel用パーティション */
+
+/* 引数定義 */
+#define OPTION_CYLINDER_DEFAULT ( 10 )      /** 引数シリンダ数デフォルト値 */
+#define OPTION_HEAD_DEFAULT     ( 16 )      /** 引数ヘッド数デフォルト値   */
+#define OPTION_SECTOR_DEFAULT   ( 63 )      /** 引数セクタ数デフォルト値   */
+
+/* シリンダ定義 */
+#define CYLINDER_MIN            (    0 )    /** シリンダ最小値 */
+#define CYLINDER_MAX            ( 1023 )    /** シリンダ最大値 */
+
+/* ヘッド定義 */
+#define HEAD_MIN                (   0 )     /** セクタ最小値 */
+#define HEAD_MAX                ( 254 )     /** セクタ最大値 */
+
+/* セクタ定義 */
+#define SECTOR_MIN              (  1 )      /** セクタ最小値 */
+#define SECTOR_MAX              ( 63 )      /** セクタ最大値 */
+
+/** バッファサイズ */
+#define BUFFER_SIZE             ( 512 )     /** 読込みバッファサイズ */
+
+/** アボートマクロ */
+#define ABORT( ... )                    \
+    {                                   \
+        /* エラー出力 */                \
+        fprintf( stderr, __VA_ARGS__ ); \
+        fprintf( stderr, "\n" );        \
+                                        \
+        /* USAGE出力 */                 \
+        printUsage( EXIT_FAILURE );     \
+    }
+
+/** CS設定マクロ */
+#define SET_CYL_SEC( _CYLINDER, _SECTOR )   \
+    ( ( ( _CYLINDER & 0x0300 ) << 6 ) |     \
+      ( ( _SECTOR   & 0x003F ) << 8 ) |     \
+      (   _CYLINDER & 0x00FF        )   )
+
+/** CYLINDER取得マクロ */
+#define GET_CYLINDER( _CYLSEC )     \
+    ( ( ( _CYLSEC >> 6 ) & 0x0300 ) | ( _CYLSEC & 0x00FF ) )
+
+/** SECTOR取得マクロ */
+#define GET_SECTOR( _CYLSEC ) ( ( _CYLSEC >> 8 ) & 0x3F )
+
+/** CHSアドレス */
+typedef struct {
+    uint16_t cylSec;            /**< シリンダ&セクタ */
+    uint8_t  head;              /**< ヘッド          */
+}  __attribute__( ( packed ) ) chs_t;
+
+/** パーティションテーブル */
+typedef struct {
+    uint8_t  status;            /**< ステータス           */
+    chs_t    chsFirstAddr;      /**< CHS先頭アドレス      */
+    uint8_t  type;              /**< パーティションタイプ */
+    chs_t    chsLastAddr;       /**< CHS最後尾アドレス    */
+    uint32_t lbaFirstAddr;      /**< LBA先頭アドレス      */
+    uint32_t lbaSize;           /**< LBAサイズ            */
+} __attribute__( ( packed ) ) pt_t;
+
+/** MBR */
+typedef struct {
+    uint8_t code[ 446 ];        /**< ブートストラップコード */
+    pt_t    partitionTbl[ 4 ];  /**< パーティションテーブル */
+    uint8_t signature[ 2 ];     /**< ブートシグネチャ       */
+} __attribute__( ( packed ) ) mbr_t;
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+/* オプションチェック */
+static void checkOptions( int32_t argNum,
+                          char    *pArg[],
+                          char    **ppDiskPath,
+                          char    **ppIplPath,
+                          char    **ppBootPath,
+                          char    **ppKernelPath );
+/* CHSアドレス取得 */
+static chs_t getChs( uint32_t lba );
+
+/* USAGE出力 */
+static void printUsage( int status );
+
+/* IPLバイナリ書込み */
+static void writeIpl( int  diskFd,
+                      char *pIplPath );
+
+/* ブートローダバイナリ書込み */
+static chs_t writeBoot( int   diskFd,
+                        char  *pBootPath,
+                        chs_t chsFirstAddr );
+
+/* カーネルバイナリ書込み */
+static chs_t writeKernel( int   diskFd,
+                          char  *pKernelPath,
+                          chs_t chsFirstAddr  );
+
+/* パーティションエントリ書込み */
+static void writePartitionEntry( int      diskFd,
+                                 uint32_t no,
+                                 pt_t     *pPe    );
+
+
+/******************************************************************************/
+/* グローバル変数定義                                                         */
+/******************************************************************************/
+uint32_t cylinder;  /* 仮想ディスクのシリンダ数 */
+uint32_t head;      /* 仮想ディスクのヘッド数   */
+uint32_t sector;    /* 仮想ディスクのセクタ数   */
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       makedisk
+ * @details     仮想マシン用ディスクイメージを作成する。
+ * 
+ * param[in]    argNum  引数の数
+ * param[in]    *pArg[] 引数
+ * 
+ * retval       EXIT_SUCCESS 正常終了
+ * retval       EXIT_FAILURE 異常終了
+ */
+/******************************************************************************/
+int main( int  argNum,
+          char *pArg[] )
+{
+    int      diskFd;        /* 仮想ディスクファイルディスクリプタ */
+    char     *pDiskPath;    /* 仮想ディスクパス                   */
+    char     *pIplPath;     /* IPLバイナリパス                    */
+    char     *pBootPath;    /* ブートローダバイナリパス           */
+    char     *pKernelPath;  /* カーネルバイナリパス               */
+    char     end;           /* 仮想ディスク最終バイト             */
+    chs_t    chs;           /* CHSアドレス                        */
+    off_t    offset;        /* オフセット                         */
+    int32_t  size;          /* 書込みサイズ                       */
+    uint32_t aaaaacylinder;      /* シリンダ                           */
+    
+    /* 初期化 */
+    end = 0;
+    memset( &chs, 0, sizeof ( chs_t ) );
+    
+    /* オプションチェック */
+    checkOptions( argNum,
+                  pArg,
+                  &pDiskPath,
+                  &pIplPath,
+                  &pBootPath,
+                  &pKernelPath );
+    
+    /* 仮想ディスクオープン */
+    diskFd = open( pDiskPath,
+                   O_RDWR | O_CREAT | O_TRUNC,
+                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH );
+    
+    /* オープン結果判定 */
+    if ( diskFd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               pDiskPath,
+               errno );
+    }
+    
+    /* IPLバイナリ書込み */
+    writeIpl( diskFd, pIplPath );
+    
+    /* ブートローダバイナリ書込み */
+    chs.cylSec   = SET_CYL_SEC( 0, 1 );
+    chs.head     = 1;
+    chs = writeBoot( diskFd, pBootPath, chs );
+    
+    /* カーネルバイナリ書込み */
+    chs.cylSec = SET_CYL_SEC( GET_CYLINDER( chs.cylSec ) + 1, 1 );
+    chs.head   = 0;
+    chs = writeKernel( diskFd, pKernelPath, chs );
+    
+    /* 仮想ディスクファイルサイズチェック */
+    if ( GET_CYLINDER( chs.cylSec ) < cylinder ) {
+        /* 指定サイズ未達 */
+        
+        /* 仮想ディスクシーク */
+        offset = lseek( diskFd, cylinder * head * sector * 512 - 1, SEEK_SET );
+        
+        /* シーク結果判定 */
+        if ( ( int32_t ) offset != ( cylinder * head * sector * 512 - 1 ) ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't seek at the disk image. ret=%d, errno=%d.\n",
+                   __LINE__,
+                   ( int32_t ) offset,
+                   errno );
+        }
+        
+        /* 書込み */
+        size = ( int32_t ) write( diskFd, &end, 1 );
+        
+        /* 書込み結果判定 */
+        if ( size != 1 ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't write %s. ret=%d, errno=%d.\n",
+                   __LINE__,
+                   pDiskPath,
+                   size,
+                   errno );
+        }
+        
+    } else {
+        /* 指定サイズ過達 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Overwrite.CHS=%u/%u/%u > %u/%u/%u.\n",
+               __LINE__,
+               GET_CYLINDER( chs.cylSec ),
+               chs.head,
+               GET_SECTOR( chs.cylSec ),
+               cylinder,
+               head,
+               sector );
+    }
+    
+    /* 仮想ディスククローズ */
+    close( diskFd );
+    
+    /* 正常終了 */
+    return EXIT_SUCCESS;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       オプションチェック
+ * @details     オプションが許容可能な値かチェックする。
+ * 
+ * @param[in]   argNum        引数の数
+ * @param[in]   *pArg[]       引数
+ * @param[out]  *ppDiskPath   仮想ディスクのファイルパス
+ * @param[out]  *ppIplPath    IPLバイナリのファイルパス
+ * @param[out]  *ppBootPath   ブートローダバイナリのファイルパス
+ * @param[out]  *ppKernelPath カーネルバイナリのファイルパス
+ */
+/******************************************************************************/
+static void checkOptions( int32_t argNum,
+                          char    *pArg[],
+                          char    **ppDiskPath,
+                          char    **ppIplPath,
+                          char    **ppBootPath,
+                          char    **ppKernelPath )
+{
+    char opt;   /* オプション文字 */
+    
+    /* 初期化 */
+    *ppDiskPath   = NULL;                   /* 仮想ディスクパス         */
+    *ppIplPath    = NULL;                   /* IPLバイナリパス          */
+    *ppBootPath   = NULL;                   /* ブートローダバイナリパス */
+    *ppKernelPath = NULL;                   /* カーネルバイナルパス     */
+    cylinder      = OPTION_CYLINDER_DEFAULT;/* デフォルトシリンダ       */
+    head          = OPTION_HEAD_DEFAULT;    /* デフォルトヘッド         */
+    sector        = OPTION_SECTOR_DEFAULT;  /* デフォルトセクタ         */
+    
+    /* オプションが無くなるまで繰り返し */
+    while ( true ) {
+        /* オプション取得 */
+        opt = getopt( argNum, pArg, "o:i:b:k:C:H:S:h" );
+        
+        /* 取得結果判定 */
+        if ( opt == -1 ) {
+            /* オプション無し */
+            break;
+            
+        } else if ( opt == 'o' ) {
+            /* 仮想ディスクパス */
+            *ppDiskPath = optarg;
+            
+        } else if ( opt == 'i' ) {
+            /* IPLバイナリパス */
+            *ppIplPath = optarg;
+            
+        } else if ( opt == 'b' ) {
+            /* ブートローダバイナリパス */
+            *ppBootPath = optarg;
+            
+        } else if ( opt == 'k' ) {
+            /* カーネルバイナリパス */
+            *ppKernelPath = optarg;
+            
+        } else if ( opt == 'C' ) {
+            /* シリンダ */
+            cylinder = ( uint32_t ) atoi( optarg );
+            
+        } else if ( opt == 'H' ) {
+            /* ヘッダ */
+            head = ( uint32_t ) atoi( optarg );
+            
+        } else if ( opt == 'S' ) {
+            /* セクタ */
+            sector = ( uint32_t ) atoi( optarg );
+            
+        } else if ( opt == 'h' ) {
+            /* ヘルプ */
+            
+            /* USAGE出力して終了 */
+            printUsage( EXIT_SUCCESS );
+            
+        } else {
+            /* 他 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Unknown option!\n", __LINE__ );
+        }
+    }
+    
+    /* 仮想ディスクパス設定チェック */
+    if ( *ppDiskPath == NULL ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No '-o' option!\n", __LINE__ );
+    }
+    
+    /* IPLバイナリパス設定チェック */
+    if ( *ppIplPath == NULL ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No '-i' option!\n", __LINE__ );
+    }
+    
+    /* ブートローダバイナリパス設定チェック */
+    if ( *ppBootPath == NULL ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No '-b' option!\n", __LINE__ );
+    }
+    
+    /* カーネルバイナリパス設定チェック */
+    if ( *ppKernelPath == NULL ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No '-k' option!\n", __LINE__ );
+    }
+    
+    /* シリンダ値チェック */
+    if ( !( ( CYLINDER_MIN <= cylinder     ) &&
+            ( cylinder     <= CYLINDER_MAX )    ) ) {
+        /* 範囲外 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): cylinder(%u) is out of range(%u-%u).\n",
+               __LINE__,
+               cylinder,
+               CYLINDER_MIN,
+               CYLINDER_MAX );
+    }
+    
+    /* ヘッド値チェック */
+    if ( !( ( HEAD_MIN <= head     ) &&
+            ( head     <= HEAD_MAX )    ) ) {
+        /* 範囲外 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Head(%u) is out of range(%u-%u).\n",
+               __LINE__,
+               head,
+               HEAD_MIN,
+               HEAD_MAX );
+    }
+    
+    /* セクタ値チェック */
+    if ( !( ( SECTOR_MIN <= sector     ) &&
+            ( sector     <= SECTOR_MAX )    ) ) {
+        /* 範囲外 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Sector(%u) is out of range(%u-%u).\n",
+               __LINE__,
+               sector,
+               CYLINDER_MIN,
+               CYLINDER_MAX );
+    }
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       CHSアドレス取得
+ * @details     LBAアドレスをCHSアドレスに変換して取得する。
+ * 
+ * @param[in]   lba LBAアドレス
+ * 
+ * @return      CHSアドレス
+ */
+/******************************************************************************/
+static chs_t getChs( uint32_t lba )
+{
+    chs_t chs;  /* CHSアドレス */
+    
+    /* 初期化 */
+    memset( &chs, 0, sizeof ( chs_t ) );
+    
+    /* CHSアドレス設定 */
+    chs.cylSec   = SET_CYL_SEC( ( lba / sector ) / head,
+                                lba % sector + 1 );
+    chs.head     = ( lba / sector ) % head;
+    
+    return chs;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       USAGE出力
+ * @details     USAGEを出力しプログラムを終了する。
+ * 
+ * @param[in]   status 終了ステータス
+ */
+/******************************************************************************/
+static void printUsage( int status )
+{
+    /* USAGE出力 */
+    fprintf( stderr, "USAGE: makedisk -o [FILE] -b [FILE] -k [FILE] [OPTION]...\n"                                 );
+    fprintf( stderr, "\n"                                                                                          );
+    fprintf( stderr, "Option:\n"                                                                                   );
+    fprintf( stderr, "  -o FILE   specify the output FILE that is a disk image.\n"                                 );
+    fprintf( stderr, "  -i FILE   specify the input FILE that is a IPL binary.\n"                                  );
+    fprintf( stderr, "  -b FILE   specify the input FILE that is a boot loader binary.\n"                          );
+    fprintf( stderr, "  -k FILE   specify the input FILE that is a kernel binary.\n"                               );
+    fprintf( stderr, "  -C NUMBER specify the NUMBER of cylinders.(default:%u)\n",         OPTION_CYLINDER_DEFAULT );
+    fprintf( stderr, "  -H NUMBER specify the NUMBER of heads.(default:%u)\n",             OPTION_HEAD_DEFAULT     );
+    fprintf( stderr, "  -S NUMBER specify the NUMBER of sectors per track.(default:%u)\n", OPTION_SECTOR_DEFAULT   );
+    fprintf( stderr, "  -h        print help.\n"                                                                   );
+    
+    /* 終了 */
+    exit( status );
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       IPLバイナリ書込み
+ * @details     IPLバイナリを仮想ディスクに書き込む。
+ * 
+ * @param[in]   diskFd    仮想ディスクファイルディスクリプタ
+ * @param[in]   *pIplPath IPLバイナリのファイルパス
+ */
+/******************************************************************************/
+static void writeIpl( int  diskFd,
+                      char *pIplPath )
+{
+    int     iplFd;  /* IPLバイナリファイルディスクリプタ */
+    mbr_t   mbr;    /* マスタブートレコード              */
+    int32_t size;   /* サイズ                            */
+    
+    /* IPLバイナリファイルオープン */
+    iplFd = open( pIplPath, O_RDONLY );
+    
+    /* オープン結果判定 */
+    if ( iplFd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               pIplPath,
+               errno );
+    }
+    
+    /* IPLバイナリ読込み */
+    size = ( int32_t ) read( iplFd, &mbr, sizeof ( mbr_t ) );
+    
+    /* 読込み結果判定 */
+    if ( size != ( sizeof ( mbr_t ) ) ) {
+        /* 読込み失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't read from %s. ret=%d, errno=%d.\n",
+               __LINE__,
+               pIplPath,
+               size,
+               errno );
+    }
+    
+    /* IPLバイナリを仮想ディスクに書込み */
+    size = ( int32_t ) write( diskFd, &mbr, sizeof ( mbr_t ) );
+    
+    /* 書込み結果判定 */
+    if ( size != ( sizeof ( mbr_t ) ) ) {
+        /* 書込み */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't write %s. ret=%d, errno=%d.\n",
+               __LINE__,
+               pIplPath,
+               size,
+               errno );
+    }
+    
+    /* ファイルクローズ */
+    close( iplFd );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       ブートローダバイナリ書込み
+ * @details     ブートローダバイナリを仮想ディスクのパーティション1番に書込む。
+ * 
+ * @param[in]   diskFd       仮想ディスクファイルディスクリプタ
+ * @param[in]   *pBootPath   ブートローダバイナリのファイルパス
+ * @param[in]   chsFirstAddr 書込み先先頭CHSアドレス
+ * 
+ * @return      書込み先最後尾CHSアドレス
+ */
+/******************************************************************************/
+static chs_t writeBoot( int   diskFd,
+                        char  *pBootPath,
+                        chs_t chsFirstAddr )
+{
+    int      bootFd;                /* ブートローダファイルディスクリプタ */
+    pt_t     pe;                    /* パーティションエントリ             */
+    char     buffer[ BUFFER_SIZE ]; /* 読込みバッファ                     */
+    off_t    offset;                /* ファイルオフセット                 */
+    int32_t  readSize;              /* 読込サイズ                         */
+    int32_t  writeSize;             /* 書込みサイズ                       */
+    uint32_t fileSize;              /* ファイルサイズ                     */
+    uint32_t lbaSize;               /* ファイルサイズ(セクタ数)         */
+    uint32_t lbaFirstAddr;          /* 書込み先先頭LBAアドレス            */
+    
+    /* 初期化 */
+    fileSize = 0;
+    lbaSize  = 0;
+    lbaFirstAddr = GET_CYLINDER( chsFirstAddr.cylSec ) * head * sector +
+                   chsFirstAddr.head * sector + 
+                   GET_SECTOR( chsFirstAddr.cylSec ) - 1;
+    memset( &pe, 0, sizeof ( pt_t ) );
+    
+    /* 仮想ディスクシーク */
+    offset = lseek( diskFd, lbaFirstAddr * 512, SEEK_SET );
+    
+    /* シーク結果判定 */
+    if ( ( int32_t ) offset != ( lbaFirstAddr * 512 ) ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the disk image. ret=%d, errno=%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* ブートローダバイナリファイルオープン */
+    bootFd = open( pBootPath, O_RDONLY );
+    
+    /* オープン結果判定 */
+    if ( bootFd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               pBootPath,
+               errno );
+    }
+    
+    /* 読み書きバッファサイズ毎に繰り返し */
+    do {
+        /* バッファ初期化 */
+        memset( buffer, 0, BUFFER_SIZE );
+        
+        /* ブートローダバイナリ読込み */
+        readSize = read( bootFd, buffer, BUFFER_SIZE );
+        
+        /* 読込み結果判定 */
+        if ( readSize == -1 ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't read from %s. errno=%d.\n",
+                   __LINE__,
+                   pBootPath,
+                   errno );
+            
+        } else if ( readSize == 0 ) {
+            /* EOF */
+            
+            break;
+        }
+        
+        /* 書込み */
+        writeSize = write( diskFd, buffer, readSize );
+        
+        /* 書込み結果判定 */
+        if ( writeSize != readSize ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't write %s. errno=%d.\n",
+                   __LINE__,
+                   pBootPath,
+                   errno );
+        }
+        
+        /* ファイルサイズ更新 */
+        fileSize += writeSize;
+        lbaSize++;
+    } while ( writeSize == BUFFER_SIZE );
+    
+    /* パーティションテーブル設定 */
+    pe.status       = PT_STATUS_BOOT;
+    pe.chsFirstAddr = chsFirstAddr;
+    pe.type         = PT_TYPE_MOCHI_BOOTER;
+    pe.chsLastAddr  = getChs( lbaFirstAddr + lbaSize - 1 );
+    pe.lbaFirstAddr = lbaFirstAddr;
+    pe.lbaSize      = lbaSize;
+    writePartitionEntry( diskFd, 1, &pe );
+    
+    /* ファイルクローズ */
+    close( bootFd );
+    
+    return pe.chsLastAddr;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       カーネルバイナリ書込み
+ * @details     カーネルバイナリを仮想ディスクのパーティション2番に書込む。
+ * 
+ * @param[in]   diskFd       仮想ディスクファイルディスクリプタ
+ * @param[in]   *pKernelPath カーネルバイナリのファイルパス
+ * @param[in]   chsFirstAddr 書込み先先頭CHSアドレス
+ * 
+ * @return      書込み先最後尾CHSアドレス
+ */
+/******************************************************************************/
+static chs_t writeKernel( int   diskFd,
+                          char  *pKernelPath,
+                          chs_t chsFirstAddr  )
+{
+    int      kernelFd;              /* カーネルファイルディスクリプタ */
+    pt_t     pe;                    /* パーティションエントリ         */
+    char     buffer[ BUFFER_SIZE ]; /* 読込みバッファ                 */
+    off_t    offset;                /* ファイルオフセット             */
+    int32_t  readSize;              /* 読込サイズ                     */
+    int32_t  writeSize;             /* 書込みサイズ                   */
+    uint32_t fileSize;              /* ファイルサイズ                 */
+    uint32_t lbaSize;               /* ファイルサイズ(セクタ数)     */
+    uint32_t lbaFirstAddr;          /* 書込み先先頭LBAアドレス        */
+    
+    /* 初期化 */
+    fileSize     = 0;
+    lbaSize      = 0;
+    lbaFirstAddr = GET_CYLINDER( chsFirstAddr.cylSec ) * head * sector +
+                   chsFirstAddr.head * sector + 
+                   GET_SECTOR( chsFirstAddr.cylSec ) - 1;
+    memset( &pe, 0, sizeof ( pt_t ) );
+    
+    /* 仮想ディスクシーク */
+    offset = lseek( diskFd, lbaFirstAddr * 512, SEEK_SET );
+    
+    /* シーク結果判定 */
+    if ( ( int32_t ) offset != ( lbaFirstAddr * 512 ) ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the disk image. ret=%d, errno=%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* カーネルバイナリファイルオープン */
+    kernelFd = open( pKernelPath, O_RDONLY );
+    
+    /* オープン結果判定 */
+    if ( kernelFd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               pKernelPath,
+               errno );
+    }
+    
+    /* 読み書きバッファサイズ毎に繰り返し */
+    do {
+        /* バッファ初期化 */
+        memset( buffer, 0, BUFFER_SIZE );
+        
+        /* ブートローダバイナリ読込み */
+        readSize = read( kernelFd, buffer, BUFFER_SIZE );
+        
+        /* 読込み結果判定 */
+        if ( readSize == -1 ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't read from %s. errno=%d.\n",
+                   __LINE__,
+                   pKernelPath,
+                   errno );
+            
+        } else if ( readSize == 0 ) {
+            /* EOF */
+            
+            break;
+        }
+        
+        /* 書込み */
+        writeSize = write( diskFd, buffer, readSize );
+        
+        /* 書込み結果判定 */
+        if ( writeSize != readSize ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't write %s. errno=%d.\n",
+                   __LINE__,
+                   pKernelPath,
+                   errno );
+        }
+        
+        /* ファイルサイズ更新 */
+        fileSize += writeSize;
+        lbaSize++;
+    } while ( writeSize == BUFFER_SIZE );
+    
+    /* パーティションテーブル設定 */
+    pe.status       = 0;
+    pe.chsFirstAddr = chsFirstAddr;
+    pe.type         = PT_TYPE_MOCHI_KERNEL;
+    pe.chsLastAddr  = getChs( lbaFirstAddr + lbaSize - 1 );
+    pe.lbaFirstAddr = lbaFirstAddr;
+    pe.lbaSize      = lbaSize;
+    writePartitionEntry( diskFd, 2, &pe );
+    
+    /* ファイルクローズ */
+    close( kernelFd );
+    
+    return pe.chsLastAddr;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       パーティションエントリ書込み
+ * @details     パーティションテーブルのエントリを仮想ディスクに書き込む。
+ * 
+ * @param[in]   diskFd 仮想ディスクファイルディスクリプタ
+ * @param[in]   no     パーティション番号
+ * @param[in]   *pPe   パーティションエントリ
+ */
+/******************************************************************************/
+static void writePartitionEntry( int      diskFd,
+                                 uint32_t no,
+                                 pt_t     *pPe    )
+{
+    int     iplFd;  /* IPLバイナリファイルディスクリプタ */
+    mbr_t   mbr;    /* マスタブートレコード              */
+    off_t   offset; /* ファイルオフセット                */
+    int32_t size;   /* サイズ                            */
+    
+    /* 仮想ディスクシーク */
+    offset = lseek( diskFd, 0, SEEK_SET );
+    
+    /* シーク結果判定 */
+    if ( ( int32_t ) offset != 0 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the disk image. ret=%d, errno=%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* MBR読込み */
+    size = ( int32_t ) read( diskFd, &mbr, sizeof ( mbr_t ) );
+    
+    /* 読込み結果判定 */
+    if ( size != ( sizeof ( mbr_t ) ) ) {
+        /* 読込み失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't read from MBR. ret=%d, errno=%d.\n",
+               __LINE__,
+               size,
+               errno );
+    }
+    
+    /* パーティションエントリ設定 */
+    mbr.partitionTbl[ no - 1 ] = *pPe;
+    
+    /* 仮想ディスクシーク */
+    offset = lseek( diskFd, 0, SEEK_SET );
+    
+    /* シーク結果判定 */
+    if ( ( int32_t ) offset != 0 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the disk image. ret=%d, errno=%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* MBR書込み */
+    size = ( int32_t ) write( diskFd, &mbr, sizeof ( mbr_t ) );
+    
+    /* 書込み結果判定 */
+    if ( size != ( sizeof ( mbr_t ) ) ) {
+        /* 書込み */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't write MBR. ret=%d, errno=%d.\n",
+               __LINE__,
+               size,
+               errno );
+    }
+    
+    return;
+}
+
+
+/******************************************************************************/