From e8f0b6da3eed8e86a409b5160a0c722f49c06bf0 Mon Sep 17 00:00:00 2001 From: Mochi Date: Tue, 11 Jul 2017 23:53:50 +0900 Subject: [PATCH] =?utf8?q?MochiBooter=E3=81=AE=E5=A4=A7=E5=B9=85=E6=94=B9?= =?utf8?q?=E9=80=A0=EF=BC=88ATA-PIOread=E3=81=AB=E3=82=88=E3=82=8B?= =?utf8?q?=E3=82=AB=E3=83=BC=E3=83=8D=E3=83=AB=E3=83=AD=E3=83=BC=E3=83=89?= =?utf8?q?=EF=BC=89=E3=80=81VM=E3=82=A4=E3=83=A1=E3=83=BC=E3=82=B8?= =?utf8?q?=E4=BD=9C=E6=88=90=E3=83=84=E3=83=BC=E3=83=AB=E8=BF=BD=E5=8A=A0?= =?utf8?q?=E3=81=AA=E3=81=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- build/Makefile | 19 +- build/ptable.bin | Bin 64 -> 0 bytes src/Makefile | 7 +- src/booter/Debug/DebugInit.c | 51 + src/booter/Debug/DebugLog.c | 1180 ++++++++++++++++++++ src/booter/Debug/DebugLog.h | 16 + src/booter/Driver/DriverA20.c | 252 +++++ src/booter/Driver/DriverAta.c | 323 ++++++ src/booter/Driver/DriverAta.h | 16 + src/booter/Driver/DriverInit.c | 55 + .../InitctrlCpu.s => InitCtrl/InitCtrlInit16.s} | 49 +- src/booter/InitCtrl/InitCtrlInit32.c | 108 ++ src/booter/Initctrl/InitctrlA20.s | 125 --- src/booter/Initctrl/InitctrlMain.s | 45 - src/booter/IntMng/IntMngHdl.c | 248 ++++ src/booter/IntMng/IntMngHdl.h | 16 + src/booter/IntMng/IntMngIdt.c | 137 +++ src/booter/IntMng/IntMngIdt.h | 41 + src/booter/IntMng/IntMngInit.c | 65 ++ src/booter/IntMng/IntMngPic.c | 348 ++++++ src/booter/IntMng/IntMngPic.h | 16 + src/booter/Ipl/IplMain.s | 32 +- src/booter/LoadMng/LoadMngInit.c | 82 ++ src/booter/LoadMng/LoadMngInit.h | 50 + src/booter/LoadMng/LoadMngKernel.c | 63 ++ src/booter/Loader/LoaderLoad.s | 51 - src/booter/Makefile | 43 +- src/booter/booter-main.lds | 12 +- src/booter/include/Cmn.h | 67 ++ src/booter/include/Debug.h | 35 + src/booter/include/Driver.h | 45 + src/booter/include/IntMng.h | 59 + src/booter/include/LoadMng.h | 26 + src/include/MLib/Basic/MLibBasic.h | 4 +- src/include/hardware/ATA/ATA.h | 77 ++ src/{kernel => }/include/hardware/I8254/I8254.h | 0 src/{kernel => }/include/hardware/I8259A/I8259A.h | 0 src/{kernel => }/include/hardware/IA32/IA32.h | 0 .../include/hardware/IA32/IA32Descriptor.h | 0 .../include/hardware/IA32/IA32Instruction.h | 50 +- .../include/hardware/IA32/IA32Paging.h | 0 src/{kernel => }/include/hardware/IA32/IA32Tss.h | 0 src/{kernel => }/include/hardware/Vga/Vga.h | 0 src/include/kernel/MochiKernel.h | 6 +- src/kernel/Makefile | 2 +- src/kernel/ProcMng/ProcMngElf.c | 10 +- src/libraries/Makefile | 14 +- src/tools/Makefile | 49 + src/tools/makedisk/Makefile | 56 + src/tools/makedisk/makedisk.c | 873 +++++++++++++++ 50 files changed, 4531 insertions(+), 292 deletions(-) delete mode 100644 build/ptable.bin create mode 100644 src/booter/Debug/DebugInit.c create mode 100644 src/booter/Debug/DebugLog.c create mode 100644 src/booter/Debug/DebugLog.h create mode 100644 src/booter/Driver/DriverA20.c create mode 100644 src/booter/Driver/DriverAta.c create mode 100644 src/booter/Driver/DriverAta.h create mode 100644 src/booter/Driver/DriverInit.c rename src/booter/{Initctrl/InitctrlCpu.s => InitCtrl/InitCtrlInit16.s} (68%) create mode 100644 src/booter/InitCtrl/InitCtrlInit32.c delete mode 100644 src/booter/Initctrl/InitctrlA20.s delete mode 100644 src/booter/Initctrl/InitctrlMain.s create mode 100644 src/booter/IntMng/IntMngHdl.c create mode 100644 src/booter/IntMng/IntMngHdl.h create mode 100644 src/booter/IntMng/IntMngIdt.c create mode 100644 src/booter/IntMng/IntMngIdt.h create mode 100644 src/booter/IntMng/IntMngInit.c create mode 100644 src/booter/IntMng/IntMngPic.c create mode 100644 src/booter/IntMng/IntMngPic.h create mode 100644 src/booter/LoadMng/LoadMngInit.c create mode 100644 src/booter/LoadMng/LoadMngInit.h create mode 100644 src/booter/LoadMng/LoadMngKernel.c delete mode 100644 src/booter/Loader/LoaderLoad.s create mode 100644 src/booter/include/Cmn.h create mode 100644 src/booter/include/Debug.h create mode 100644 src/booter/include/Driver.h create mode 100644 src/booter/include/IntMng.h create mode 100644 src/booter/include/LoadMng.h create mode 100644 src/include/hardware/ATA/ATA.h rename src/{kernel => }/include/hardware/I8254/I8254.h (100%) rename src/{kernel => }/include/hardware/I8259A/I8259A.h (100%) rename src/{kernel => }/include/hardware/IA32/IA32.h (100%) rename src/{kernel => }/include/hardware/IA32/IA32Descriptor.h (100%) rename src/{kernel => }/include/hardware/IA32/IA32Instruction.h (92%) rename src/{kernel => }/include/hardware/IA32/IA32Paging.h (100%) rename src/{kernel => }/include/hardware/IA32/IA32Tss.h (100%) rename src/{kernel => }/include/hardware/Vga/Vga.h (100%) create mode 100644 src/tools/Makefile create mode 100644 src/tools/makedisk/Makefile create mode 100644 src/tools/makedisk/makedisk.c diff --git a/build/Makefile b/build/Makefile index 13143fc..42a52dc 100644 --- a/build/Makefile +++ b/build/Makefile @@ -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 index f009ca03c021dba68cf1c6513dac02ea2361832f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64 ncmZQzP-JT6w_{=8U|?9!&A`CGZ_m=qZ_l}2n1Nv<5EB9b&X)vi diff --git a/src/Makefile b/src/Makefile index 86c2c97..703be49 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 index 0000000..4a2f84d --- /dev/null +++ b/src/booter/Debug/DebugInit.c @@ -0,0 +1,51 @@ +/******************************************************************************/ +/* src/booter/Debug/DebugInit.c */ +/* 2017/06/26 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include + +/* 外部モジュールヘッダ */ +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..a02da56 --- /dev/null +++ b/src/booter/Debug/DebugLog.c @@ -0,0 +1,1180 @@ +/******************************************************************************/ +/* src/booter/Debug/DebugLog.c */ +/* 2017/07/04 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..f60770f --- /dev/null +++ b/src/booter/Debug/DebugLog.h @@ -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 index 0000000..3fbe19e --- /dev/null +++ b/src/booter/Driver/DriverA20.c @@ -0,0 +1,252 @@ +/******************************************************************************/ +/* src/booter/Driver/DriverA20.c */ +/* 2017/07/10 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* デバッグトレースログ出力マクロ */ +#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 index 0000000..2ac7c68 --- /dev/null +++ b/src/booter/Driver/DriverAta.c @@ -0,0 +1,323 @@ +/******************************************************************************/ +/* src/booter/Driver/DriverAta.c */ +/* 2017/07/11 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* デバッグトレースログ出力マクロ */ +#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 index 0000000..35be2e8 --- /dev/null +++ b/src/booter/Driver/DriverAta.h @@ -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 index 0000000..13f1cc3 --- /dev/null +++ b/src/booter/Driver/DriverInit.c @@ -0,0 +1,55 @@ +/******************************************************************************/ +/* src/booter/Driver/DriverInit.c */ +/* 2017/07/03 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 外部モジュールヘッダ */ +#include +#include + +/* 内部モジュールヘッダ */ +#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; +} + + +/******************************************************************************/ diff --git a/src/booter/Initctrl/InitctrlCpu.s b/src/booter/InitCtrl/InitCtrlInit16.s similarity index 68% rename from src/booter/Initctrl/InitctrlCpu.s rename to src/booter/InitCtrl/InitCtrlInit16.s index 9ba9a6e..53aab26 100644 --- a/src/booter/Initctrl/InitctrlCpu.s +++ b/src/booter/InitCtrl/InitCtrlInit16.s @@ -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 /******************************************************************************/ @@ -16,7 +22,18 @@ /******************************************************************************/ .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 index 0000000..67509a4 --- /dev/null +++ b/src/booter/InitCtrl/InitCtrlInit32.c @@ -0,0 +1,108 @@ +/******************************************************************************/ +/* src/booter/InitCtrl/InitCtrlInit32.c */ +/* 2017/07/11 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include +#include +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* デバッグトレースログ出力マクロ */ +#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 index 60b48a0..0000000 --- a/src/booter/Initctrl/InitctrlA20.s +++ /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 index 0f0e286..0000000 --- a/src/booter/Initctrl/InitctrlMain.s +++ /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 index 0000000..db6a08c --- /dev/null +++ b/src/booter/IntMng/IntMngHdl.c @@ -0,0 +1,248 @@ +/******************************************************************************/ +/* src/booter/IntMng/IntMngHdl.c */ +/* 2017/07/03 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..e151282 --- /dev/null +++ b/src/booter/IntMng/IntMngHdl.h @@ -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 index 0000000..19eb7f2 --- /dev/null +++ b/src/booter/IntMng/IntMngIdt.c @@ -0,0 +1,137 @@ +/******************************************************************************/ +/* src/booter/IntMng/IntMngIdt.c */ +/* 2017/07/03 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..06a76ed --- /dev/null +++ b/src/booter/IntMng/IntMngIdt.h @@ -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 + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* 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 index 0000000..4c37c5f --- /dev/null +++ b/src/booter/IntMng/IntMngInit.c @@ -0,0 +1,65 @@ +/******************************************************************************/ +/* src/booter/IntMng/IntMngInit.c */ +/* 2017/07/03 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ + +/* 外部モジュールヘッダ */ +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..251f9cc --- /dev/null +++ b/src/booter/IntMng/IntMngPic.c @@ -0,0 +1,348 @@ +/******************************************************************************/ +/* src/booter/IntMng/IntMngPic.c */ +/* 2017/07/03 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..cf6a58d --- /dev/null +++ b/src/booter/IntMng/IntMngPic.h @@ -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 diff --git a/src/booter/Ipl/IplMain.s b/src/booter/Ipl/IplMain.s index c6ec5c8..d6308aa 100644 --- a/src/booter/Ipl/IplMain.s +++ b/src/booter/Ipl/IplMain.s @@ -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 index 0000000..182171c --- /dev/null +++ b/src/booter/LoadMng/LoadMngInit.c @@ -0,0 +1,82 @@ +/******************************************************************************/ +/* src/booter/LoadMng/LoadMngInit.c */ +/* 2017/07/05 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 0000000..08f678d --- /dev/null +++ b/src/booter/LoadMng/LoadMngInit.h @@ -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 + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/** 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 index 0000000..48f75d1 --- /dev/null +++ b/src/booter/LoadMng/LoadMngKernel.c @@ -0,0 +1,63 @@ +/******************************************************************************/ +/* src/booter/LoadMng/LoadMngKernel.c */ +/* 2017/07/11 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include +#include + +/* 内部モジュールヘッダ */ +#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 index 923350c..0000000 --- a/src/booter/Loader/LoaderLoad.s +++ /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) */ - - -/******************************************************************************/ diff --git a/src/booter/Makefile b/src/booter/Makefile index 1f553c2..7238069 100644 --- a/src/booter/Makefile +++ b/src/booter/Makefile @@ -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 #******************************************************************************# diff --git a/src/booter/booter-main.lds b/src/booter/booter-main.lds index 9c891ed..e07980f 100644 --- a/src/booter/booter-main.lds +++ b/src/booter/booter-main.lds @@ -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 index 0000000..7a1c886 --- /dev/null +++ b/src/booter/include/Cmn.h @@ -0,0 +1,67 @@ +/******************************************************************************/ +/* src/booter/include/Cmn.h */ +/* 2017/07/04 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +#ifndef CMN_H +#define CMN_H +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* 処理結果 */ +#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 index 0000000..e0b75a1 --- /dev/null +++ b/src/booter/include/Debug.h @@ -0,0 +1,35 @@ +/******************************************************************************/ +/* src/booter/include/Debug.h */ +/* 2017/06/26 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +#ifndef DEBUG_H +#define DEBUG_H +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +#include +#include + + +/******************************************************************************/ +/* グローバル関数プロトタイプ宣言 */ +/******************************************************************************/ +/*-------------*/ +/* 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 index 0000000..1639e58 --- /dev/null +++ b/src/booter/include/Driver.h @@ -0,0 +1,45 @@ +/******************************************************************************/ +/* src/booter/include/Driver.h */ +/* 2017/06/26 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +#ifndef DRIVER_H +#define DRIVER_H +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 外部モジュールヘッダ */ +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/*--------------* + * 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 index 0000000..9518b72 --- /dev/null +++ b/src/booter/include/IntMng.h @@ -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 index 0000000..afe74ed --- /dev/null +++ b/src/booter/include/LoadMng.h @@ -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 diff --git a/src/include/MLib/Basic/MLibBasic.h b/src/include/MLib/Basic/MLibBasic.h index 1742fc1..8a0673b 100644 --- a/src/include/MLib/Basic/MLibBasic.h +++ b/src/include/MLib/Basic/MLibBasic.h @@ -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 index 0000000..1fe9a84 --- /dev/null +++ b/src/include/hardware/ATA/ATA.h @@ -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 diff --git a/src/kernel/include/hardware/I8254/I8254.h b/src/include/hardware/I8254/I8254.h similarity index 100% rename from src/kernel/include/hardware/I8254/I8254.h rename to src/include/hardware/I8254/I8254.h diff --git a/src/kernel/include/hardware/I8259A/I8259A.h b/src/include/hardware/I8259A/I8259A.h similarity index 100% rename from src/kernel/include/hardware/I8259A/I8259A.h rename to src/include/hardware/I8259A/I8259A.h diff --git a/src/kernel/include/hardware/IA32/IA32.h b/src/include/hardware/IA32/IA32.h similarity index 100% rename from src/kernel/include/hardware/IA32/IA32.h rename to src/include/hardware/IA32/IA32.h diff --git a/src/kernel/include/hardware/IA32/IA32Descriptor.h b/src/include/hardware/IA32/IA32Descriptor.h similarity index 100% rename from src/kernel/include/hardware/IA32/IA32Descriptor.h rename to src/include/hardware/IA32/IA32Descriptor.h diff --git a/src/kernel/include/hardware/IA32/IA32Instruction.h b/src/include/hardware/IA32/IA32Instruction.h similarity index 92% rename from src/kernel/include/hardware/IA32/IA32Instruction.h rename to src/include/hardware/IA32/IA32Instruction.h index 0e80339..f94e902 100644 --- a/src/kernel/include/hardware/IA32/IA32Instruction.h +++ b/src/include/hardware/IA32/IA32Instruction.h @@ -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 #include #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 diff --git a/src/kernel/include/hardware/IA32/IA32Paging.h b/src/include/hardware/IA32/IA32Paging.h similarity index 100% rename from src/kernel/include/hardware/IA32/IA32Paging.h rename to src/include/hardware/IA32/IA32Paging.h diff --git a/src/kernel/include/hardware/IA32/IA32Tss.h b/src/include/hardware/IA32/IA32Tss.h similarity index 100% rename from src/kernel/include/hardware/IA32/IA32Tss.h rename to src/include/hardware/IA32/IA32Tss.h diff --git a/src/kernel/include/hardware/Vga/Vga.h b/src/include/hardware/Vga/Vga.h similarity index 100% rename from src/kernel/include/hardware/Vga/Vga.h rename to src/include/hardware/Vga/Vga.h diff --git a/src/include/kernel/MochiKernel.h b/src/include/kernel/MochiKernel.h index 4bf60f7..45d5ce9 100644 --- a/src/include/kernel/MochiKernel.h +++ b/src/include/kernel/MochiKernel.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/include/kernel/MochiKernel.h */ -/* 2017/05/24 */ +/* 2017/07/11 */ /* Copyright (C) 2017 Mochi */ /******************************************************************************/ #ifndef _MOCHI_KERNEL_H_ @@ -15,6 +15,10 @@ /******************************************************************************/ /* 定義 */ /******************************************************************************/ +/* カーネル位置 */ +#define MOCHIKERNEL_ADDR_ENTRY ( 0x00100000 ) /** エントリポイント */ +#define MOCHIKERNEL_ADDR_STACK ( 0x04000000 ) /** スタックアドレス */ + /* メモリ領域タイプ */ #define MOCHIKERNEL_MEMORY_TYPE_AVAILABLE ( 0x01 ) /** 使用可能メモリ領域 */ #define MOCHIKERNEL_MEMORY_TYPE_RESERVED ( 0x02 ) /** 使用不可メモリ領域 */ diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 65b408c..7459313 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -1,6 +1,6 @@ #******************************************************************************# #* src/kernel/Makefile *# -#* 2017/06/01 *# +#* 2017/07/06 *# #* Copyright (C) 2016-2017 Mochi. *# #******************************************************************************# #******************************************************************************# diff --git a/src/kernel/ProcMng/ProcMngElf.c b/src/kernel/ProcMng/ProcMngElf.c index 8e41e8d..59dbe7b 100644 --- a/src/kernel/ProcMng/ProcMngElf.c +++ b/src/kernel/ProcMng/ProcMngElf.c @@ -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 ) ) ) { /* 不正値 */ /* デバッグトレースログ出力 */ diff --git a/src/libraries/Makefile b/src/libraries/Makefile index 24ac4e9..ce5c466 100644 --- a/src/libraries/Makefile +++ b/src/libraries/Makefile @@ -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 index 0000000..c73f847 --- /dev/null +++ b/src/tools/Makefile @@ -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 index 0000000..08a3c4b --- /dev/null +++ b/src/tools/makedisk/Makefile @@ -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 index 0000000..9d758fd --- /dev/null +++ b/src/tools/makedisk/makedisk.c @@ -0,0 +1,873 @@ +/******************************************************************************/ +/* src/tools/makedisk/makedisk.c */ +/* 2017/07/02 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* パーティションテーブル定義 */ +#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; +} + + +/******************************************************************************/ -- 2.11.0