From 933f2280a1c6f82b6b5a3221a5c30886013e3164 Mon Sep 17 00:00:00 2001 From: Mochi Date: Fri, 16 Jun 2017 22:03:24 +0900 Subject: [PATCH 1/1] =?utf8?q?ELF=E3=83=AD=E3=83=BC=E3=83=80=E8=BF=BD?= =?utf8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/include/MLib/Basic/MLibBasic.h | 8 +- src/include/elf.h | 124 ++++++ src/kernel/Debug/DebugLog.c | 3 +- src/kernel/Makefile | 3 +- src/kernel/MemMng/MemMngCtrl.c | 109 +++-- src/kernel/MemMng/MemMngPage.c | 46 +- src/kernel/ProcMng/ProcMngElf.c | 483 +++++++++++++++++++++ src/kernel/ProcMng/ProcMngElf.h | 31 ++ src/kernel/ProcMng/ProcMngSched.c | 30 +- src/kernel/ProcMng/ProcMngSched.h | 4 +- src/kernel/ProcMng/ProcMngTask.c | 196 +++++---- src/kernel/ProcMng/ProcMngTask.h | 30 +- src/kernel/include/Cmn.h | 41 +- src/kernel/include/Config.h | 26 ++ src/kernel/include/MemMng.h | 35 +- src/kernel/include/ProcMng.h | 14 +- src/kernel/include/hardware/IA32/IA32Instruction.h | 53 +-- src/kernel/include/hardware/IA32/IA32Paging.h | 27 +- 18 files changed, 1011 insertions(+), 252 deletions(-) create mode 100644 src/include/elf.h create mode 100644 src/kernel/ProcMng/ProcMngElf.c create mode 100644 src/kernel/ProcMng/ProcMngElf.h create mode 100644 src/kernel/include/Config.h diff --git a/src/include/MLib/Basic/MLibBasic.h b/src/include/MLib/Basic/MLibBasic.h index c71e2c7..1742fc1 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/02/11 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi */ /******************************************************************************/ #ifndef _MLIB_BASIC_H_ @@ -9,9 +9,13 @@ /* 定義 */ /******************************************************************************/ /** アライメント計算マクロ */ -#define MLIB_BASIC_ALIGN( _VALUE, _ALIGNMENT ) \ +#define MLIB_BASIC_ALIGN( _VALUE, _ALIGNMENT ) \ ( ( ( _VALUE ) + ( ( _ALIGNMENT ) - 1 ) ) & ~( ( _ALIGNMENT ) - 1 ) ) +/** フラグ判定マクロ */ +#define MLIB_BASIC_IS_FLAG( _VALUE, _FLAG ) \ + ( ( ( _VALUE ) & ( _FLAG ) ) == ( _FLAG ) ) + /******************************************************************************/ #endif diff --git a/src/include/elf.h b/src/include/elf.h new file mode 100644 index 0000000..00cd48e --- /dev/null +++ b/src/include/elf.h @@ -0,0 +1,124 @@ +/******************************************************************************/ +/* src/include/elf.h */ +/* 2017/06/16 */ +/* Copyright (C) 2017 Mochi */ +/******************************************************************************/ +#ifndef _ELF_H_ +#define _ELF_H_ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +#include + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* ELF識別インデックス */ +#define EI_MAG0 ( 0 ) /** ファイル識別 */ +#define EI_MAG1 ( 1 ) /** ファイル識別 */ +#define EI_MAG2 ( 2 ) /** ファイル識別 */ +#define EI_MAG3 ( 3 ) /** ファイル識別 */ +#define EI_CLASS ( 4 ) /** ファイルクラス */ +#define EI_DATA ( 5 ) /** データエンコーディング */ +#define EI_VERSION ( 6 ) /** ファイルバージョン */ +#define EI_OSABI ( 7 ) /** OS/ABI識別 */ +#define EI_ABIVERSION ( 8 ) /** ABIバージョン */ +#define EI_PAD ( 9 ) /** パディング開始 */ +#define EI_NIDENT ( 16 ) /** ELF識別フィールド長 */ + +/* ファイル識別 */ +#define ELFMAG0 ( 0x7F ) /** ファイル識別子 */ +#define ELFMAG1 ( 'E' ) /** ファイル識別子 */ +#define ELFMAG2 ( 'L' ) /** ファイル識別子 */ +#define ELFMAG3 ( 'F' ) /** ファイル識別子 */ + +/* ファイルクラス */ +#define ELFCLASSNONE ( 0 ) /** 無効クラス */ +#define ELFCLASS32 ( 1 ) /** 32bitオブジェクト */ +#define ELFCLASS64 ( 2 ) /** 64bitオブジェクト */ + +/* データエンコーディング */ +#define ELFDATANONE ( 0 ) /** 無効データエンコーディング */ +#define ELFDATA2LSB ( 1 ) /** 2の補数、リトルエンディアン */ +#define ELFDATA2MSB ( 2 ) /** 2の補数、ビッグエンディアン */ + +/* オブジェクトファイルタイプ */ +#define ET_NONE ( 0 ) /** ファイルタイプ無し */ +#define ET_REL ( 1 ) /** 再配置可能ファイル */ +#define ET_EXEC ( 2 ) /** 実行可能ファイル */ +#define ET_DYN ( 3 ) /** 共有オブジェクトファイル */ +#define ET_CORE ( 4 ) /** コアファイル */ +#define ET_LOOS ( 0xFE00 ) /** OS固有(最小値) */ +#define ET_HIOS ( 0xFEFF ) /** OS固有(最大値) */ +#define ET_LOPROC ( 0xFF00 ) /** プロセッサ固有(最小値) */ +#define ET_HIPROC ( 0xFFFF ) /** プロセッサ固有(最大値) */ + +/* マシンアーキテクチャ */ +#define EM_NONE ( 0 ) /** マシンアーキテクチャ未定義 */ +#define EM_M32 ( 1 ) /** AT&T WE 32100 */ +#define EM_SPARC ( 2 ) /** SPARC */ +#define EM_386 ( 3 ) /** Intelアーキテクチャ */ +#define EM_68K ( 4 ) /** Motorola 68000 */ +#define EM_88K ( 5 ) /** Motorola 88000 */ +#define EM_860 ( 7 ) /** Intel 80860 */ +#define EM_MIPS ( 8 ) /** MIPS R3000 ビッグエンディアン */ + +/* オブジェクトファイルバージョン */ +#define EV_NONE ( 0 ) /** 不正バージョン */ +#define EV_CURRENT ( 1 ) /** カレントバージョン */ + +/* セグメントタイプ */ +#define PT_NULL ( 0 ) /** 未使用セグメント */ +#define PT_LOAD ( 1 ) /** ロード可能セグメント */ +#define PT_DYNAMIC ( 2 ) /** 動的リンク情報 */ +#define PT_INTERP ( 3 ) /** インタプリタ情報 */ +#define PT_NOTE ( 4 ) /** 補足情報 */ +#define PT_SHLIB ( 5 ) /** 未定義セグメント */ +#define PT_PHDR ( 6 ) /** プログラムヘッダテーブル */ + +/* フラグ */ +#define PF_X ( 0x00000001 ) /** 実行可能セグメント */ +#define PF_W ( 0x00000002 ) /** 書込み可能セグメント */ +#define PF_R ( 0x00000004 ) /** 読込み可能セグメント */ + +/* 32bitデータ型 */ +typedef uint32_t Elf32_Addr; /** プログラムアドレス */ +typedef uint16_t Elf32_Half; /** 符号無2バイト整数 */ +typedef uint32_t Elf32_Off; /** ファイルオフセット */ +typedef int32_t Elf32_Sword; /** 符号有4バイト整数 */ +typedef uint32_t Elf32_Word; /** 符号無4バイト整数 */ + +/** ELFヘッダ */ +typedef struct { + unsigned char e_ident[ EI_NIDENT ]; /**< ELF識別 */ + Elf32_Half e_type; /**< オブジェクトファイルタイプ */ + Elf32_Half e_machine; /**< マシンアーキテクチャ */ + Elf32_Word e_version; /**< オブジェクトファイルバージョン */ + Elf32_Addr e_entry; /**< エントリポイント(仮想アドレス) */ + Elf32_Off e_phoff; /**< PHTファイルオフセット */ + Elf32_Off e_shoff; /**< SHTファイルオフセット */ + Elf32_Word e_flags; /**< プロセッサ固有フラグ */ + Elf32_Half e_ehsize; /**< ELFヘッダサイズ */ + Elf32_Half e_phentsize; /**< PHTエントリサイズ */ + Elf32_Half e_phnum; /**< PHTエントリ数 */ + Elf32_Half e_shentsize; /**< SHTエントリサイズ */ + Elf32_Half e_shnum; /**< SHTエントリ数 */ + Elf32_Half e_shstrndx; /**< SHTインデックス */ +} Elf32_Ehdr; + +/** プログラムヘッダ */ +typedef struct { + Elf32_Word p_type; /**< セグメントタイプ */ + Elf32_Off p_offset; /**< ファイルオフセット */ + Elf32_Addr p_vaddr; /**< 仮想メモリアドレス */ + Elf32_Addr p_paddr; /**< 物理メモリアドレス */ + Elf32_Word p_filesz; /**< ファイルサイズ */ + Elf32_Word p_memsz; /**< メモリサイズ */ + Elf32_Word p_flags; /**< フラグ */ + Elf32_Word p_align; /**< アライメント値 */ +} Elf32_Phdr; + + +/******************************************************************************/ +#endif diff --git a/src/kernel/Debug/DebugLog.c b/src/kernel/Debug/DebugLog.c index c3c54b9..9c50ca4 100644 --- a/src/kernel/Debug/DebugLog.c +++ b/src/kernel/Debug/DebugLog.c @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/Debug/DebugLog.c */ -/* 2017/05/24 */ +/* 2017/05/31 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ /******************************************************************************/ @@ -99,6 +99,7 @@ const static logIdTrans_t gIdTransTbl[ CMN_MODULE_NUM + 1 ] = { { CMN_MODULE_PROCMNG_TSS, "PRC-TSS " }, /* プロセス管理(TSS管理) */ { CMN_MODULE_PROCMNG_SCHED, "PRC-SCHD" }, /* プロセス管理(スケジューラ) */ { CMN_MODULE_PROCMNG_TASK, "PRC-TASK" }, /* プロセス管理(タスク管理) */ + { CMN_MODULE_PROCMNG_ELF, "PRC-ELF " }, /* プロセス管理(ELFローダ) */ { CMN_MODULE_DEBUG_INIT, "DBG-INIT" }, /* デバッグ制御(初期化) */ { CMN_MODULE_DEBUG_LOG, "DBG-LOG " }, /* デバッグ制御(ログ管理) */ { 0, "UNKNOWN " } };/* 終端 */ diff --git a/src/kernel/Makefile b/src/kernel/Makefile index cd38d07..65b408c 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -1,6 +1,6 @@ #******************************************************************************# #* src/kernel/Makefile *# -#* 2017/05/18 *# +#* 2017/06/01 *# #* Copyright (C) 2016-2017 Mochi. *# #******************************************************************************# #******************************************************************************# @@ -29,6 +29,7 @@ SRCS = InitCtrl/InitCtrlInit.c \ ProcMng/ProcMngTss.c \ ProcMng/ProcMngTask.c \ ProcMng/ProcMngSched.c \ + ProcMng/ProcMngElf.c \ Debug/DebugInit.c \ Debug/DebugLog.c diff --git a/src/kernel/MemMng/MemMngCtrl.c b/src/kernel/MemMng/MemMngCtrl.c index 24dd87a..049476b 100644 --- a/src/kernel/MemMng/MemMngCtrl.c +++ b/src/kernel/MemMng/MemMngCtrl.c @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/MemMng/MemMngCtrl.c */ -/* 2017/05/19 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ /******************************************************************************/ @@ -12,9 +12,11 @@ #include #include #include +#include /* 外部モジュールヘッダ */ #include +#include #include #include @@ -26,21 +28,14 @@ /******************************************************************************/ /* デバッグトレースログ出力マクロ */ #ifdef DEBUG_LOG_ENABLE -#define DEBUG_LOG( ... ) \ - DebugLogOutput( CMN_MODULE_MEMMNG_CTRL, \ - __LINE__, \ +#define DEBUG_LOG( ... ) \ + DebugLogOutput( CMN_MODULE_MEMMNG_CTRL, \ + __LINE__, \ __VA_ARGS__ ) #else #define DEBUG_LOG( ... ) #endif -/* 物理マッピング用領域定義 */ -#define CTRL_MAP_ADDR1 ( 0x3F000000 ) /** 物理マッピング用領域1先頭アドレス */ -#define CTRL_MAP_ADDR2 ( 0x3F800000 ) /** 物理マッピング用領域2先頭アドレス */ -#define CTRL_MAP_SIZE ( 0x01000000 ) /** 物理マッピング用領域全サイズ */ -#define CTRL_MAP_SIZE1 ( 0x00800000 ) /** 物理マッピング用領域1サイズ */ -#define CTRL_MAP_SIZE2 ( 0x00800000 ) /** 物理マッピング用領域2サイズ */ - /******************************************************************************/ /* グローバル関数定義 */ @@ -54,16 +49,17 @@ * @param[in] pVAddr コピー元仮想アドレス * @param[in] size コピーサイズ * - * @attention 引数pPhysAddrは4KiBアライメントであること。 + * @attention 引数pPAddrは4KiBアライメントであること。 */ /******************************************************************************/ void MemMngCtrlCopyVirtToPhys( void *pPAddr, void *pVAddr, size_t size ) { - uint32_t dirId; /* ページディレクトリID */ - uint32_t idx; /* インデックス */ - size_t count; /* コピーサイズ */ + size_t count; /* コピーサイズ */ + uint32_t pageDirId; /* ページディレクトリID */ + uint32_t idx; /* インデックス */ + CmnRet_t ret; /* 関数戻り値 */ /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() start.", __func__ ); @@ -73,39 +69,49 @@ void MemMngCtrlCopyVirtToPhys( void *pPAddr, size ); /* ページディレクトリID取得 */ - dirId = MemMngPageGetDirId(); + pageDirId = MemMngPageGetDirId(); /* 物理マッピング用領域サイズ毎に繰り返し */ - for ( idx = 0; idx < size; idx += CTRL_MAP_SIZE ) { + for ( idx = 0; idx < size; idx += CONFIG_MEM_KERNEL_MAP_SIZE ) { /* 次コピー有無判定 */ - if ( ( size - idx ) > CTRL_MAP_SIZE ) { + if ( ( size - idx ) > CONFIG_MEM_KERNEL_MAP_SIZE ) { /* 次コピー有 */ /* コピーサイズ設定 */ - count = CTRL_MAP_SIZE; + count = CONFIG_MEM_KERNEL_MAP_SIZE; } else { /* 次コピー無 */ /* コピーサイズ設定 */ - count = size - idx; + count = MLIB_BASIC_ALIGN( size - idx, + IA32_PAGING_PAGE_SIZE ); } /* ページマッピング設定 */ - MemMngPageSet( dirId, - ( void * ) CTRL_MAP_ADDR1, - pPAddr + idx, - count, - IA32_PAGING_G_NO, - IA32_PAGING_US_SV, - IA32_PAGING_RW_RW ); + ret = MemMngPageSet( pageDirId, + ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, + pPAddr + idx, + count, + IA32_PAGING_G_NO, + IA32_PAGING_US_SV, + IA32_PAGING_RW_RW ); + + /* 設定結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* [TODO] */ + } /* コピー */ - memcpy( ( void * ) CTRL_MAP_ADDR1, pVAddr + idx, count ); + memcpy( ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, pVAddr + idx, count ); } /* ページマッピング解除 */ - MemMngPageUnset( dirId, ( void * ) CTRL_MAP_ADDR1, CTRL_MAP_SIZE ); + MemMngPageUnset( pageDirId, + ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, + CONFIG_MEM_KERNEL_MAP_SIZE ); /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() end.", __func__ ); @@ -130,9 +136,10 @@ void MemMngCtrlSet( void *pPAddr, uint8_t value, size_t size ) { - uint32_t dirId; /* ページディレクトリID */ - uint32_t idx; /* インデックス */ - size_t count; /* コピーサイズ */ + size_t count; /* コピーサイズ */ + uint32_t pageDirId; /* ページディレクトリID */ + uint32_t idx; /* インデックス */ + CmnRet_t ret; /* 関数戻り値 */ /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() start. pPAddr=%010p, value=%0#4X, size=%#X", @@ -142,39 +149,49 @@ void MemMngCtrlSet( void *pPAddr, size ); /* ページディレクトリID取得 */ - dirId = MemMngPageGetDirId(); + pageDirId = MemMngPageGetDirId(); /* 物理マッピング用領域サイズ毎に繰り返し */ - for ( idx = 0; idx < size; idx += CTRL_MAP_SIZE ) { + for ( idx = 0; idx < size; idx += CONFIG_MEM_KERNEL_MAP_SIZE ) { /* 次設定有無判定 */ - if ( ( size - idx ) > CTRL_MAP_SIZE ) { + if ( ( size - idx ) > CONFIG_MEM_KERNEL_MAP_SIZE ) { /* 次設定有 */ /* サイズ設定 */ - count = CTRL_MAP_SIZE; + count = CONFIG_MEM_KERNEL_MAP_SIZE; } else { /* 次設定無 */ /* サイズ設定 */ - count = size - idx; + count = MLIB_BASIC_ALIGN( size - idx, + IA32_PAGING_PAGE_SIZE ); } /* ページマッピング設定 */ - MemMngPageSet( dirId, - ( void * ) CTRL_MAP_ADDR1, - pPAddr + idx, - count, - IA32_PAGING_G_NO, - IA32_PAGING_US_SV, - IA32_PAGING_RW_RW ); + ret = MemMngPageSet( pageDirId, + ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, + pPAddr + idx, + count, + IA32_PAGING_G_NO, + IA32_PAGING_US_SV, + IA32_PAGING_RW_RW ); + + /* 設定結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* [TODO] */ + } /* メモリ設定 */ - memset( ( void * ) CTRL_MAP_ADDR1, value, count ); + memset( ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, value, count ); } /* ページマッピング解除 */ - MemMngPageUnset( dirId, ( void * ) CTRL_MAP_ADDR1, CTRL_MAP_SIZE ); + MemMngPageUnset( pageDirId, + ( void * ) CONFIG_MEM_KERNEL_MAP_ADDR1, + CONFIG_MEM_KERNEL_MAP_SIZE ); /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() end.", __func__ ); diff --git a/src/kernel/MemMng/MemMngPage.c b/src/kernel/MemMng/MemMngPage.c index 8a8c39a..7080686 100644 --- a/src/kernel/MemMng/MemMngPage.c +++ b/src/kernel/MemMng/MemMngPage.c @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/MemMng/MemMngPage.c */ -/* 2017/05/21 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ /******************************************************************************/ @@ -36,8 +36,8 @@ #endif /* テーブル使用フラグ */ -#define PAGE_UNUSED ( 0 ) /**< 未使用テーブル */ -#define PAGE_USED ( 1 ) /**< 使用中テーブル */ +#define PAGE_UNUSED ( 0 ) /** 未使用テーブル */ +#define PAGE_USED ( 1 ) /** 使用中テーブル */ /** ページ管理テーブル構造体 */ typedef struct { @@ -204,28 +204,33 @@ uint32_t MemMngPageGetDirId( void ) /******************************************************************************/ /** * @brief ページディレクトリ切替 - * @details 指定したページディレクトリをCPUに設定する。 + * @details 指定したページディレクトリに切り替える。 * - * @param[in] id ページディレクトリID + * @param[in] pageDirId ページディレクトリID + * + * @return ページディレクトリベースレジスタ */ /******************************************************************************/ -void MemMngPageSwitchDir( uint32_t id ) +IA32PagingPDBR_t MemMngPageSwitchDir( uint32_t pageDirId ) { - /* デバッグトレースログ出力 */ - DEBUG_LOG( "%s() start. id=%u", __func__, id ); + IA32PagingPDBR_t pdbr; /* 戻り値 */ - /* CPU設定 */ - IA32InstructionSetCr3( &gPageDir[ id ], - IA32_PAGING_PCD_ENABLE, - IA32_PAGING_PWT_WB ); + /* デバッグトレースログ出力 *//* + DEBUG_LOG( "%s() start. pageDirId=%u", __func__, pageDirId );*/ /* 現ページディレクトリID設定 */ - gPageMngTbl.nowDirId = id; + gPageMngTbl.nowDirId = pageDirId; - /* デバッグトレースログ出力 */ - DEBUG_LOG( "%s() end.", __func__ ); + /* PDBR作成 */ + IA32_PAGING_SET_PDBR( pdbr, + &gPageDir[ pageDirId ], + IA32_PAGING_PCD_ENABLE, + IA32_PAGING_PWT_WB ); - return; + /* デバッグトレースログ出力 *//* + DEBUG_LOG( "%s() end.", __func__ );*/ + + return pdbr; } @@ -237,7 +242,8 @@ void MemMngPageSwitchDir( uint32_t id ) /******************************************************************************/ void MemMngPageInit( void ) { - CmnRet_t ret; /* 戻り値 */ + CmnRet_t ret; /* 戻り値 */ + IA32PagingPDBR_t pdbr; /* PDBR */ /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() start.", __func__ ); @@ -263,8 +269,11 @@ void MemMngPageInit( void ) /* [TODO] */ } + /* ページディレクトリ切替 */ + pdbr = MemMngPageSwitchDir( MEMMNG_PAGE_DIR_ID_IDLE ); + /* ページディレクトリ設定 */ - MemMngPageSwitchDir( MEMMNG_PAGE_DIR_ID_IDLE ); + IA32InstructionSetCr3( pdbr ); /* ページング有効化 */ IA32InstructionSetCr0( IA32_CR0_PG, IA32_CR0_PG ); @@ -408,7 +417,6 @@ void MemMngPageUnset( uint32_t dirId, size -= IA32_PAGING_PAGE_SIZE; } - /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() end.", __func__ ); diff --git a/src/kernel/ProcMng/ProcMngElf.c b/src/kernel/ProcMng/ProcMngElf.c new file mode 100644 index 0000000..8e41e8d --- /dev/null +++ b/src/kernel/ProcMng/ProcMngElf.c @@ -0,0 +1,483 @@ +/******************************************************************************/ +/* src/kernel/ProcMng/ProcMngElf.c */ +/* 2017/06/13 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include +#include +#include +#include + +/* 外部モジュールヘッダ */ +#include +#include +#include +#include +#include + +/* 内部モジュールヘッダ */ +#include "ProcMngTask.h" + + +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* デバッグトレースログ出力マクロ */ +#ifdef DEBUG_LOG_ENABLE +#define DEBUG_LOG( ... ) \ + DebugLogOutput( CMN_MODULE_PROCMNG_ELF, \ + __LINE__, \ + __VA_ARGS__ ) +#else +#define DEBUG_LOG( ... ) +#endif + + +/******************************************************************************/ +/* ローカル関数プロトタイプ宣言 */ +/******************************************************************************/ +/* ELFヘッダチェック */ +static CmnRet_t ElfCheckElfHeader( void *pAddr, + size_t size ); + +/* プログラムヘッダチェック */ +static CmnRet_t ElfCheckPrgHeader( void *pAddr, + size_t size ); + + +/******************************************************************************/ +/* グローバル関数定義 */ +/******************************************************************************/ +/******************************************************************************/ +/** + * @brief ELFファイル読込 + * @details ELFファイルをメモリを読み込む。 + * + * @param[in] *pAddr ELFファイルアドレス + * @param[in] size ELFファイルサイズ + * @param[out] *pTaskInfo タスク情報 + * + * @retval CMN_SUCCESS 正常終了 + * @retval CMN_FAILURE 異常終了 + */ +/******************************************************************************/ +CmnRet_t ProcMngElfLoad( void *pAddr, + size_t size, + ProcMngTaskTbl_t *pTaskInfo ) +{ + void *pPhyAddr; /* 物理アドレス */ + uint32_t index; /* インデックス */ + uint32_t attrRw; /* 読込/書込許可属性 */ + CmnRet_t ret; /* 関数戻り値 */ + Elf32_Ehdr *pElfHdr; /* ELFヘッダ */ + Elf32_Phdr *pPrgHdr; /* プログラムヘッダテーブル */ + Elf32_Phdr *pEntry; /* プログラムヘッダテーブルエントリ */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() start.", __func__ ); + DEBUG_LOG( " pAddr=%010p, size=%u, pTaskInfo=%010p", + pAddr, + size, + pTaskInfo ); + + /* 初期化 */ + pElfHdr = ( Elf32_Ehdr * ) pAddr; + pPrgHdr = ( Elf32_Phdr * ) ( ( uint32_t ) pAddr + pElfHdr->e_phoff ); + + /* ELFヘッダチェック */ + ret = ElfCheckElfHeader( pAddr, size ); + + /* チェック結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 不正 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + + return CMN_FAILURE; + } + + /* プログラムヘッダチェック */ + ret = ElfCheckPrgHeader( pAddr, size ); + + /* チェック結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 不正 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + + return CMN_FAILURE; + } + + /* プログラムヘッダテーブル1エントリ毎に繰り返し */ + for ( index = 0; index < pElfHdr->e_phnum; index++ ) { + /* プログラムヘッダ参照変数設定 */ + pEntry = ( Elf32_Phdr * ) ( ( uint32_t ) pPrgHdr + + pElfHdr->e_phentsize * index ); + + /* セグメントタイプ判定 */ + if ( pEntry->p_type != PT_LOAD ) { + /* ロード可能セグメント以外 */ + + /* 次のプログラムヘッダテーブルエントリ */ + continue; + } + + /* セグメントサイズ取得 */ + size = MLIB_BASIC_ALIGN( pEntry->p_memsz, IA32_PAGING_PAGE_SIZE ); + + /* メモリ領域割当 */ + pPhyAddr = MemMngAreaAlloc( size ); + + /* メモリ領域割当結果判定 */ + if ( pPhyAddr == NULL ) { + /* 失敗 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + + return CMN_FAILURE; + } + + /* 0初期化 */ + MemMngCtrlSet( pPhyAddr, 0, size ); + + /* セグメントコピー */ + MemMngCtrlCopyVirtToPhys( + pPhyAddr, + ( void * ) ( ( uint32_t ) pAddr + pEntry->p_offset ), + pEntry->p_filesz ); + + /* フラグ判定 */ + if ( MLIB_BASIC_IS_FLAG( pEntry->p_flags, PF_R | PF_W ) ) { + /* 読書可能セグメント */ + + attrRw = IA32_PAGING_RW_RW; + + } else { + /* 読込専用セグメント */ + + attrRw = IA32_PAGING_RW_R; + } + + /* ページマッピング設定 */ + ret = MemMngPageSet( pTaskInfo->pageDirId, + ( void * ) pEntry->p_vaddr, + pPhyAddr, + size, + IA32_PAGING_G_NO, + IA32_PAGING_US_USER, + attrRw ); + + /* 設定結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + + return CMN_FAILURE; + } + } + + /* エントリポイント設定 */ + pTaskInfo->pEntryPoint = ( void * ) pElfHdr->e_entry; + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ ); + + return CMN_SUCCESS; +} + + +/******************************************************************************/ +/* ローカル関数定義 */ +/******************************************************************************/ +/******************************************************************************/ +/** + * @brief ELFヘッダチェック + * @details ELFファイルのELFヘッダが許容される内容かチェックする。 + * + * @param[in] *pAddr ELFファイルアドレス + * @param[in] size ELFファイルサイズ + * + * @retval CMN_SUCCESS 正常終了 + * @retval CMN_FAILURE 異常終了 + */ +/******************************************************************************/ +static CmnRet_t ElfCheckElfHeader( void *pAddr, + size_t size ) +{ + Elf32_Ehdr *pHdr; /* ELFヘッダ */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() start. pAddr=%010p, size=%u", + __func__, + pAddr, + size ); + + /* 初期化 */ + pHdr = ( Elf32_Ehdr * ) pAddr; + + /* ELFヘッダサイズチェック */ + if ( size < sizeof ( Elf32_Ehdr ) ) { + /* 不正 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end.", __func__ ); + + return CMN_FAILURE; + } + + /* ファイル識別子チェック */ + if ( ( pHdr->e_ident[ EI_MAG0 ] != ELFMAG0 ) || + ( pHdr->e_ident[ EI_MAG1 ] != ELFMAG1 ) || + ( pHdr->e_ident[ EI_MAG2 ] != ELFMAG2 ) || + ( pHdr->e_ident[ EI_MAG3 ] != ELFMAG3 ) ) { + /* 不正ファイル識別子 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + DEBUG_LOG( " e_ident[ EI_MAG0 ]=%02X %02X %02X %02X", + pHdr->e_ident[ EI_MAG0 ], + pHdr->e_ident[ EI_MAG1 ], + pHdr->e_ident[ EI_MAG2 ], + pHdr->e_ident[ EI_MAG3 ] ); + + return CMN_FAILURE; + } + + /* ファイルクラスチェック */ + if ( pHdr->e_ident[ EI_CLASS ] != ELFCLASS32 ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_ident[ EI_CLASS ]=0x%02X", + __func__, + pHdr->e_ident[ EI_CLASS ] ); + + return CMN_FAILURE; + } + + /* データエンコーディングチェック */ + if ( pHdr->e_ident[ EI_DATA ] != ELFDATA2LSB ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_ident[ EI_DATA ]=0x%02X", + __func__, + pHdr->e_ident[ EI_DATA ] ); + + return CMN_FAILURE; + } + + /* ファイルバージョンチェック */ + if ( pHdr->e_ident[ EI_VERSION ] != EV_CURRENT ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_ident[ EI_VERSION ]=0x%02X", + __func__, + pHdr->e_ident[ EI_VERSION ] ); + + return CMN_FAILURE; + } + + /* オブジェクトファイルタイプチェック */ + if ( pHdr->e_type != ET_EXEC ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_type=0x%04X", + __func__, + pHdr->e_type ); + + return CMN_FAILURE; + } + + /* マシンアーキテクチャチェック */ + if ( pHdr->e_machine != EM_386 ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_machine=0x%04X", + __func__, + pHdr->e_machine ); + + return CMN_FAILURE; + } + + /* ファイルバージョンチェック */ + if ( pHdr->e_version != EV_CURRENT ) { + /* 無効値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_version=0x%08X", + __func__, + pHdr->e_version ); + + return CMN_FAILURE; + } + + /* エントリポイントチェック */ + if ( ( pHdr->e_entry < CONFIG_MEM_TASK_START_ADDR ) && + ( pHdr->e_entry >= CONFIG_MEM_TASK_STACK_ADDR ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_entry=0x%08X", + __func__, + pHdr->e_entry ); + + return CMN_FAILURE; + } + + /* ELFヘッダサイズチェック */ + if ( pHdr->e_ehsize != sizeof ( Elf32_Ehdr ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, e_ehsize=0x%04X", + __func__, + pHdr->e_ehsize ); + + return CMN_FAILURE; + } + + /* プログラムヘッダテーブルサイズチェック */ + if ( size < ( pHdr->e_phoff + pHdr->e_phentsize * pHdr->e_phnum ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + DEBUG_LOG( " e_phoff=0x%08X, e_phentsize=0x%04X, e_phnum=0x%04X", + pHdr->e_phoff, + pHdr->e_phentsize, + pHdr->e_phnum ); + + return CMN_FAILURE; + } + + /* セクションヘッダテーブルサイズチェック */ + if ( size < ( pHdr->e_shoff + pHdr->e_shentsize * pHdr->e_shnum ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE", __func__ ); + DEBUG_LOG( " e_shoff=0x%08X, e_shentsize=0x%04X, e_shnum=%04X", + pHdr->e_shoff, + pHdr->e_shentsize, + pHdr->e_shnum ); + + return CMN_FAILURE; + } + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ ); + + return CMN_SUCCESS; +} + + + +/******************************************************************************/ +/** + * @brief プログラムヘッダチェック + * @details ELFファイルのプログラムヘッダが許容される内容かチェックする。 + * + * @param[in] *pAddr ELFファイルアドレス + * @param[in] size ELFファイルサイズ + * + * @retval CMN_SUCCESS 正常終了 + * @retval CMN_FAILURE 異常終了 + */ +/******************************************************************************/ +static CmnRet_t ElfCheckPrgHeader( void *pAddr, + size_t size ) +{ + uint32_t index; /* プログラムヘッダテーブルインデックス */ + Elf32_Ehdr *pElfHdr; /* ELFヘッダ */ + Elf32_Phdr *pPrgHdr; /* プログラムヘッダテーブル */ + Elf32_Phdr *pEntry; /* プログラムヘッダテーブルエントリ */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() start. pAddr=%010p, size=%u", + __func__, + pAddr, + size ); + + /* 初期化 */ + pElfHdr = ( Elf32_Ehdr * ) pAddr; + pPrgHdr = ( Elf32_Phdr * ) ( ( uint32_t ) pAddr + pElfHdr->e_phoff ); + + /* 1エントリ毎に繰り返し */ + for ( index = 0; index < pElfHdr->e_phnum; index++ ) { + /* エントリ参照変数設定 */ + pEntry = ( Elf32_Phdr * ) ( ( uint32_t ) pPrgHdr + + pElfHdr->e_phentsize * index ); + + /* セグメントタイプチェック */ + if ( pEntry->p_type != PT_LOAD ) { + /* ロード可能セグメント以外 */ + + /* 次のプログラムヘッダテーブルエントリ */ + continue; + } + + /* ファイルサイズチェック */ + if ( ( pEntry->p_offset + pEntry->p_filesz ) >= size ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, size=%d", + __func__, + pEntry->p_offset + pEntry->p_filesz ); + + return CMN_FAILURE; + } + + /* 仮想メモリチェック */ + if ( ( pEntry->p_vaddr < CONFIG_MEM_TASK_START_ADDR ) || + ( ( pEntry->p_vaddr + pEntry->p_memsz ) >= + CONFIG_MEM_TASK_STACK_ADDR ) || + ( ( pEntry->p_vaddr % IA32_PAGING_PAGE_SIZE ) != 0 ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, vaddr=%#010X, end=%#010X", + __func__, + pEntry->p_vaddr, + ( pEntry->p_vaddr + pEntry->p_memsz ) ); + + return CMN_FAILURE; + } + + /* フラグチェック */ + 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 ) ) ) { + /* 不正値 */ + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_FAILURE, p_flags=%x", + __func__, + pEntry->p_flags ); + + return CMN_FAILURE; + } + } + + /* デバッグトレースログ出力 */ + DEBUG_LOG( "%s() end. ret=CMN_SUCCESS", __func__ ); + + return CMN_SUCCESS; +} + + +/******************************************************************************/ diff --git a/src/kernel/ProcMng/ProcMngElf.h b/src/kernel/ProcMng/ProcMngElf.h new file mode 100644 index 0000000..fcf66ff --- /dev/null +++ b/src/kernel/ProcMng/ProcMngElf.h @@ -0,0 +1,31 @@ +/******************************************************************************/ +/* src/kernel/ProcMng/ProcMngElf.h */ +/* 2017/06/09 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +#ifndef PROCMNG_ELF_H +#define PROCMNG_ELF_H +/******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include + +/* 外部モジュールヘッダ */ +#include + +/* 内部モジュールヘッダ */ +#include "ProcMngTask.h" + + +/******************************************************************************/ +/* グローバル関数プロトタイプ宣言 */ +/******************************************************************************/ +/* ELFファイル読込 */ +extern CmnRet_t ProcMngElfLoad( void *pAddr, + size_t size, + ProcMngTaskTbl_t *pTaskInfo ); + + +/******************************************************************************/ +#endif diff --git a/src/kernel/ProcMng/ProcMngSched.c b/src/kernel/ProcMng/ProcMngSched.c index e93c05c..e6c6423 100644 --- a/src/kernel/ProcMng/ProcMngSched.c +++ b/src/kernel/ProcMng/ProcMngSched.c @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/ProcMng/ProcMngSched.c */ -/* 2017/05/19 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ /******************************************************************************/ @@ -45,13 +45,13 @@ #define SCHED_IDLE_IDX ( 0 ) /* タスク情報使用フラグ */ -#define SCHED_TASK_INFO_UNUSED ( 0 ) /**< 未使用 */ -#define SCHED_TASK_INFO_USED ( 1 ) /**< 使用中 */ +#define SCHED_TASK_INFO_UNUSED ( 0 ) /** 未使用 */ +#define SCHED_TASK_INFO_USED ( 1 ) /** 使用中 */ /* スケジューラ実行中レベル */ -#define SCHED_LEVEL_DRIVER ( 0 ) /**< ドライバレベル */ -#define SCHED_LEVEL_SERVER ( 1 ) /**< サーバレベル */ -#define SCHED_LEVEL_USER ( 2 ) /**< ユーザレベル */ +#define SCHED_LEVEL_DRIVER ( 0 ) /** ドライバレベル */ +#define SCHED_LEVEL_SERVER ( 1 ) /** サーバレベル */ +#define SCHED_LEVEL_USER ( 2 ) /** ユーザレベル */ /** タスク情報構造体 */ typedef struct { @@ -126,7 +126,7 @@ static schedTbl_t gSchedTbl; * @retval CMN_FAILURE 失敗 */ /******************************************************************************/ -int32_t ProcMngSchedAdd( uint32_t taskId ) +CmnRet_t ProcMngSchedAdd( uint32_t taskId ) { schedTaskInfo_t *pTaskInfo; /* タスク情報 */ @@ -334,7 +334,7 @@ void ProcMngSchedInit( void ) if ( retMLib != MLIB_SUCCESS ) { /* 失敗 */ - /* [TODO] トレース出力 */ + /* [TODO] */ } } @@ -403,7 +403,7 @@ static void SchedEnqueueToReservedGrp( schedTaskInfo_t *pTaskInfo ) if ( retMLib != MLIB_SUCCESS ) { /* 失敗 */ - /* [TODO] トレース出力 */ + /* [TODO] */ } /* デバッグトレースログ出力 */ @@ -437,7 +437,7 @@ static void SchedSwitchRunGrpRole( void ) return; } - +uint32_t __test__ = 0; /******************************************************************************/ /** * @brief タスクスイッチ @@ -453,7 +453,8 @@ static __attribute__ ( ( noinline ) ) uint32_t nextTaskId ) { void *pKernelStack; /* カーネルスタック */ - uint32_t pdId; /* ページディレクトリID */ + uint32_t pageDirId; /* ページディレクトリID */ + IA32PagingPDBR_t pdbr; /* PDBR */ ProcMngTaskContext_t context; /* コンテキスト */ /* デバッグトレースログ出力 *//* @@ -479,13 +480,14 @@ static __attribute__ ( ( noinline ) ) ProcMngTssSetEsp0( ( uint32_t ) pKernelStack ); /* ページディレクトリID取得 */ - pdId = ProcMngTaskGetPageDirId( nextTaskId ); + pageDirId = ProcMngTaskGetPageDirId( nextTaskId ); /* ページディレクトリ切替 */ - MemMngPageSwitchDir( pdId ); + pdbr = MemMngPageSwitchDir( pageDirId ); /* タスクスイッチ */ - IA32InstructionSwitchTask( ( void * ) context.eip, + IA32InstructionSwitchTask( pdbr, + ( void * ) context.eip, ( void * ) context.esp, ( void * ) context.ebp ); diff --git a/src/kernel/ProcMng/ProcMngSched.h b/src/kernel/ProcMng/ProcMngSched.h index b912878..6f281d1 100644 --- a/src/kernel/ProcMng/ProcMngSched.h +++ b/src/kernel/ProcMng/ProcMngSched.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/ProcMng/ProcMngSched.h */ -/* 2017/03/01 */ +/* 2017/06/09 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ #ifndef PROCMNG_SCHED_H @@ -14,7 +14,7 @@ /* グローバル関数プロトタイプ宣言 */ /******************************************************************************/ /* スケジュール追加 */ -extern int32_t ProcMngSchedAdd( uint32_t taskId ); +extern CmnRet_t ProcMngSchedAdd( uint32_t taskId ); /* タスクID取得 */ extern uint32_t ProcMngSchedGetTaskId( void ); diff --git a/src/kernel/ProcMng/ProcMngTask.c b/src/kernel/ProcMng/ProcMngTask.c index e5b7e36..90fa8dc 100644 --- a/src/kernel/ProcMng/ProcMngTask.c +++ b/src/kernel/ProcMng/ProcMngTask.c @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/ProcMng/ProcMngTask.c */ -/* 2017/04/16 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ /******************************************************************************/ @@ -14,11 +14,13 @@ /* 外部モジュールヘッダ */ #include +#include #include #include #include /* 内部モジュールヘッダ */ +#include "ProcMngElf.h" #include "ProcMngSched.h" #include "ProcMngTask.h" #include "ProcMngTss.h" @@ -41,36 +43,12 @@ #define TASK_ID_UNUSED ( 0 ) /** 未使用 */ #define TASK_ID_USED ( 1 ) /** 使用済 */ -/* スタックサイズ */ -#define TASK_KERNEL_STACK_SIZE ( 1024000 ) /**< カーネルスタックサイズ */ -#define TASK_STACK_SIZE ( 1024000 ) /**< スタックサイズ */ - -/** タスクスタック情報 */ -typedef struct { - void *pTopAddr; /**< 先頭アドレス */ - void *pBottomAddr; /**< 後尾アドレス */ - size_t size; /**< サイズ */ -} taskStackInfo_t; - -/** タスク管理テーブル構造体 */ -typedef struct { - uint8_t used; /**< 使用フラグ */ - uint8_t type; /**< タスクタイプ */ - uint8_t state; /**< タスク状態 */ - uint8_t reserved; /**< パディング */ - ProcMngTaskContext_t context; /**< コンテキスト */ - uint32_t pageDirId; /**< ページディレクトリID */ - void *pEntryPoint; /**< エントリポイント */ - taskStackInfo_t kernelStackInfo; /**< カーネルスタックアドレス */ - taskStackInfo_t stackInfo; /**< スタックアドレス */ -} taskTbl_t; - /******************************************************************************/ /* 変数定義 */ /******************************************************************************/ /** タスク管理テーブル */ -static taskTbl_t gTaskTbl[ PROCMNG_TASK_ID_NUM ]; +static ProcMngTaskTbl_t gTaskTbl[ PROCMNG_TASK_ID_NUM ]; /******************************************************************************/ @@ -81,11 +59,12 @@ static taskTbl_t gTaskTbl[ PROCMNG_TASK_ID_NUM ]; * @brief タスク追加 * @details タスク追加を行う。 * - * @param[in] taskType タスクタイプ + * @param[in] taskType タスクタイプ * - PROCMNG_TASK_TYPE_DRIVER ドライバ * - PROCMNG_TASK_TYPE_SERVER サーバ * - PROCMNG_TASK_TYPE_USER ユーザ - * @param[in] *pEntryPoint エントリポイント + * @param[in] *pAddr 実行ファイル + * @param[in] size 実行ファイルサイズ * * @retval PROCMNG_TASK_ID_NULL 失敗 * @retval PROCMNG_TASK_ID_MIN タスクID最小値 @@ -93,14 +72,15 @@ static taskTbl_t gTaskTbl[ PROCMNG_TASK_ID_NUM ]; */ /******************************************************************************/ uint32_t ProcMngTaskAdd( uint8_t taskType, - void *pEntryPoint ) + void *pAddr, + size_t size ) { - void *pKernelStack; /* カーネルスタック */ - void *pStack; /* スタック */ - int32_t ret; /* 関数戻り値 */ - uint32_t taskId; /* タスクID */ - uint32_t pageDirId; /* ページディレクトリID */ - taskStackInfo_t *pStackInfo; /* スタック情報 */ + void *pKernelStack; /* カーネルスタック */ + void *pStack; /* スタック */ + CmnRet_t ret; /* 関数戻り値 */ + uint32_t taskId; /* タスクID */ + uint32_t pageDirId; /* ページディレクトリID */ + ProcMngTaskStackInfo_t *pStackInfo; /* スタック情報 */ /* 初期化 */ pKernelStack = NULL; @@ -111,10 +91,11 @@ uint32_t ProcMngTaskAdd( uint8_t taskType, pStackInfo = NULL; /* デバッグトレースログ出力 */ - DEBUG_LOG( "%s() start. taskType=%u, pEntryPoint=%010p", + DEBUG_LOG( "%s() start. taskType=%u, pAddr=%010p, size=%d", __func__, taskType, - pEntryPoint ); + pAddr, + size ); /* 空タスク検索 */ for ( ; taskId < PROCMNG_TASK_ID_MAX; taskId++ ) { @@ -130,65 +111,111 @@ uint32_t ProcMngTaskAdd( uint8_t taskType, /* 失敗 */ /* [TODO] */ - /* 設定したタスクを初期化する処理。異常処理はちょっと後回し */ + + return PROCMNG_TASK_ID_NULL; + } + + /* PDBR設定 */ + + /* タスク基本設定 */ + gTaskTbl[ taskId ].used = TASK_ID_USED; + gTaskTbl[ taskId ].type = taskType; + gTaskTbl[ taskId ].state = 0; + gTaskTbl[ taskId ].context.eip = ( uint32_t ) ProcMngTaskStart; + gTaskTbl[ taskId ].context.esp = CONFIG_MEM_KERNEL_STACK_ADDR + + CONFIG_MEM_KERNEL_STACK_SIZE - + sizeof ( uint32_t ); + gTaskTbl[ taskId ].pageDirId = pageDirId; + + /* カーネルスタック情報設定 */ + pStackInfo = &( gTaskTbl[ taskId ].kernelStackInfo ); + pStackInfo->pTopAddr = ( void * ) CONFIG_MEM_KERNEL_STACK_ADDR; + pStackInfo->pBottomAddr = ( void * ) + ( CONFIG_MEM_KERNEL_STACK_ADDR + + CONFIG_MEM_KERNEL_STACK_SIZE - + sizeof ( uint32_t ) ); + pStackInfo->size = CONFIG_MEM_KERNEL_STACK_SIZE; + + /* スタック情報設定 */ + pStackInfo = &( gTaskTbl[ taskId ].stackInfo ); + pStackInfo->pTopAddr = ( void * ) CONFIG_MEM_TASK_STACK_ADDR; + pStackInfo->pBottomAddr = ( void * ) + ( CONFIG_MEM_TASK_STACK_ADDR + + CONFIG_MEM_TASK_STACK_SIZE - + sizeof ( uint32_t ) ); + pStackInfo->size = CONFIG_MEM_TASK_STACK_SIZE; + + /* ELFファイル読込 */ + ret = ProcMngElfLoad( pAddr, size, &gTaskTbl[ taskId ] ); + + /* ELFファイル読込結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* [TODO] */ return PROCMNG_TASK_ID_NULL; } /* カーネルスタック領域割り当て */ - pKernelStack = MemMngAreaAlloc( TASK_KERNEL_STACK_SIZE ); + pKernelStack = MemMngAreaAlloc( CONFIG_MEM_KERNEL_STACK_SIZE ); + + /* 割り当て結果判定 */ + if ( pKernelStack == NULL ) { + /* 失敗 */ + + /* [TODO] */ + + return PROCMNG_TASK_ID_NULL; + } /* スタック領域割り当て */ - pStack = MemMngAreaAlloc( TASK_STACK_SIZE ); + pStack = MemMngAreaAlloc( CONFIG_MEM_TASK_STACK_SIZE ); /* 割り当て結果判定 */ - if ( ( pKernelStack == NULL ) || - ( pStack == NULL ) ) { + if ( pStack == NULL ) { /* 失敗 */ /* [TODO] */ - /* 設定したタスクを初期化する処理。異常処理はちょっと後回し */ return PROCMNG_TASK_ID_NULL; } - /* ページマッピング(仮) */ - MemMngPageMap( pageDirId, - pKernelStack, - pKernelStack, - TASK_KERNEL_STACK_SIZE, - IA32_PAGING_G_NO, - IA32_PAGING_US_SV, - IA32_PAGING_RW_RW ); - MemMngPageMap( pageDirId, - pStack, - pStack, - TASK_STACK_SIZE, - IA32_PAGING_G_NO, - IA32_PAGING_US_USER, - IA32_PAGING_RW_RW ); + /* カーネルスタックページマップ設定 */ + ret = MemMngPageSet( pageDirId, + ( void * ) CONFIG_MEM_KERNEL_STACK_ADDR, + pKernelStack, + CONFIG_MEM_KERNEL_STACK_SIZE, + IA32_PAGING_G_NO, + IA32_PAGING_US_SV, + IA32_PAGING_RW_RW ); - /* タスク基本設定 */ - gTaskTbl[ taskId ].used = TASK_ID_USED; - gTaskTbl[ taskId ].type = taskType; - gTaskTbl[ taskId ].state = 0; - gTaskTbl[ taskId ].context.eip = ( uint32_t ) ProcMngTaskStart; - gTaskTbl[ taskId ].context.esp = ( uint32_t ) pKernelStack + - TASK_KERNEL_STACK_SIZE; - gTaskTbl[ taskId ].pEntryPoint = pEntryPoint; - gTaskTbl[ taskId ].pageDirId = pageDirId; + /* ページマップ設定結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* [TODO] */ + + return PROCMNG_TASK_ID_NULL; + } - /* カーネルスタック情報設定 */ - pStackInfo = &( gTaskTbl[ taskId ].kernelStackInfo ); - pStackInfo->pTopAddr = pKernelStack; - pStackInfo->pBottomAddr = pKernelStack + TASK_KERNEL_STACK_SIZE; - pStackInfo->size = TASK_KERNEL_STACK_SIZE; + /* スタックページマップ設定 */ + ret = MemMngPageSet( pageDirId, + ( void * ) CONFIG_MEM_TASK_STACK_ADDR, + pStack, + CONFIG_MEM_TASK_STACK_SIZE, + IA32_PAGING_G_NO, + IA32_PAGING_US_USER, + IA32_PAGING_RW_RW ); - /* スタック情報設定 */ - pStackInfo = &( gTaskTbl[ taskId ].stackInfo ); - pStackInfo->pTopAddr = pStack; - pStackInfo->pBottomAddr = pStack + TASK_STACK_SIZE; - pStackInfo->size = TASK_STACK_SIZE; + /* ページマップ設定結果判定 */ + if ( ret != CMN_SUCCESS ) { + /* 失敗 */ + + /* [TODO] */ + + return PROCMNG_TASK_ID_NULL; + } /* スケジューラ追加 */ ret = ProcMngSchedAdd( taskId ); @@ -198,7 +225,6 @@ uint32_t ProcMngTaskAdd( uint8_t taskType, /* 失敗 */ /* [TODO] */ - /* 設定したタスクを初期化する処理。異常処理はちょっと後回し */ return PROCMNG_TASK_ID_NULL; } @@ -349,13 +375,13 @@ void ProcMngTaskSetContext( uint32_t taskId, /******************************************************************************/ void ProcMngTaskStart( void ) { - void *pEntryPoint; /* エントリポイント */ - void *pStack; /* スタックアドレス */ - uint8_t taskType; /* タスクタイプ */ - uint32_t taskId; /* タスクID */ - uint32_t codeSegSel; /* コードセグメントセレクタ */ - uint32_t dataSegSel; /* データセグメントセレクタ */ - taskTbl_t *pTask; /* タスク管理情報 */ + void *pEntryPoint; /* エントリポイント */ + void *pStack; /* スタックアドレス */ + uint8_t taskType; /* タスクタイプ */ + uint32_t taskId; /* タスクID */ + uint32_t codeSegSel; /* コードセグメントセレクタ */ + uint32_t dataSegSel; /* データセグメントセレクタ */ + ProcMngTaskTbl_t *pTask; /* タスク管理情報 */ /* デバッグトレースログ出力 */ DEBUG_LOG( "%s() start.", __func__ ); diff --git a/src/kernel/ProcMng/ProcMngTask.h b/src/kernel/ProcMng/ProcMngTask.h index 66a66b0..d7f5cde 100644 --- a/src/kernel/ProcMng/ProcMngTask.h +++ b/src/kernel/ProcMng/ProcMngTask.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/ProcMng/ProcMngTask.h */ -/* 2017/04/16 */ +/* 2017/06/15 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ #ifndef PROCMNG_TASK_H @@ -9,7 +9,9 @@ /* インクルード */ /******************************************************************************/ /* 共通ヘッダ */ +#include #include +#include /* 外部モジュールヘッダ */ #include @@ -20,11 +22,31 @@ /******************************************************************************/ /** コンテキスト構造体 */ typedef struct { - uint32_t eip; /**< eipレジスタ */ - uint32_t esp; /**< espレジスタ */ - uint32_t ebp; /**< ebpレジスタ */ + uint32_t eip; /**< eipレジスタ */ + uint32_t esp; /**< espレジスタ */ + uint32_t ebp; /**< ebpレジスタ */ } ProcMngTaskContext_t; +/** タスクスタック情報 */ +typedef struct { + void *pTopAddr; /**< 先頭アドレス */ + void *pBottomAddr; /**< 後尾アドレス */ + size_t size; /**< サイズ */ +} ProcMngTaskStackInfo_t; + +/** タスク管理テーブル構造体 */ +typedef struct { + uint8_t used; /**< 使用フラグ */ + uint8_t type; /**< タスクタイプ */ + uint8_t state; /**< タスク状態 */ + uint8_t reserved; /**< パディング */ + ProcMngTaskContext_t context; /**< コンテキスト */ + uint32_t pageDirId; /**< ページディレクトリID */ + void *pEntryPoint; /**< エントリポイント */ + ProcMngTaskStackInfo_t kernelStackInfo; /**< カーネルスタックアドレス */ + ProcMngTaskStackInfo_t stackInfo; /**< スタックアドレス */ +} ProcMngTaskTbl_t; + /******************************************************************************/ /* グローバル関数プロトタイプ宣言 */ diff --git a/src/kernel/include/Cmn.h b/src/kernel/include/Cmn.h index 7ff3263..7738395 100644 --- a/src/kernel/include/Cmn.h +++ b/src/kernel/include/Cmn.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/include/Cmn.h */ -/* 2017/05/16 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ #ifndef CMN_H @@ -19,27 +19,28 @@ #define CMN_FAILURE ( -1 ) /** 失敗 */ /* モジュール・サブモジュール識別子 */ -#define CMN_MODULE_INIT_INIT ( 0x0101 ) /**< 初期化制御(初期化) */ -#define CMN_MODULE_MEMMNG_INIT ( 0x0201 ) /**< メモリ管理(初期化) */ -#define CMN_MODULE_MEMMNG_GDT ( 0x0202 ) /**< メモリ管理(GDT管理) */ -#define CMN_MODULE_MEMMNG_AREA ( 0x0203 ) /**< メモリ管理(メモリ領域管理) */ -#define CMN_MODULE_MEMMNG_PAGE ( 0x0204 ) /**< メモリ管理(ページ管理) */ -#define CMN_MODULE_MEMMNG_CTRL ( 0x0205 ) /**< メモリ管理(メモリ制御) */ -#define CMN_MODULE_INTMNG_INIT ( 0x0301 ) /**< 割込管理(初期化) */ -#define CMN_MODULE_INTMNG_PIC ( 0x0302 ) /**< 割込管理(PIC管理) */ -#define CMN_MODULE_INTMNG_IDT ( 0x0303 ) /**< 割込管理(IDT管理) */ -#define CMN_MODULE_INTMNG_HDL ( 0x0304 ) /**< 割込管理(ハンドラ管理) */ -#define CMN_MODULE_TIMERMNG_INIT ( 0x0401 ) /**< タイマ管理(初期化) */ -#define CMN_MODULE_TIMERMNG_PIT ( 0x0402 ) /**< タイマ管理(PIT管理) */ -#define CMN_MODULE_PROCMNG_INIT ( 0x0501 ) /**< プロセス管理(初期化) */ -#define CMN_MODULE_PROCMNG_TSS ( 0x0502 ) /**< プロセス管理(TSS管理) */ -#define CMN_MODULE_PROCMNG_SCHED ( 0x0503 ) /**< プロセス管理(スケジューラ) */ -#define CMN_MODULE_PROCMNG_TASK ( 0x0504 ) /**< プロセス管理(タスク管理) */ -#define CMN_MODULE_DEBUG_INIT ( 0x0601 ) /**< デバッグ制御(初期化) */ -#define CMN_MODULE_DEBUG_LOG ( 0x0602 ) /**< デバッグ制御(ログ管理) */ +#define CMN_MODULE_INIT_INIT ( 0x0101 ) /** 初期化制御(初期化) */ +#define CMN_MODULE_MEMMNG_INIT ( 0x0201 ) /** メモリ管理(初期化) */ +#define CMN_MODULE_MEMMNG_GDT ( 0x0202 ) /** メモリ管理(GDT管理) */ +#define CMN_MODULE_MEMMNG_AREA ( 0x0203 ) /** メモリ管理(メモリ領域管理) */ +#define CMN_MODULE_MEMMNG_PAGE ( 0x0204 ) /** メモリ管理(ページ管理) */ +#define CMN_MODULE_MEMMNG_CTRL ( 0x0205 ) /** メモリ管理(メモリ制御) */ +#define CMN_MODULE_INTMNG_INIT ( 0x0301 ) /** 割込管理(初期化) */ +#define CMN_MODULE_INTMNG_PIC ( 0x0302 ) /** 割込管理(PIC管理) */ +#define CMN_MODULE_INTMNG_IDT ( 0x0303 ) /** 割込管理(IDT管理) */ +#define CMN_MODULE_INTMNG_HDL ( 0x0304 ) /** 割込管理(ハンドラ管理) */ +#define CMN_MODULE_TIMERMNG_INIT ( 0x0401 ) /** タイマ管理(初期化) */ +#define CMN_MODULE_TIMERMNG_PIT ( 0x0402 ) /** タイマ管理(PIT管理) */ +#define CMN_MODULE_PROCMNG_INIT ( 0x0501 ) /** プロセス管理(初期化) */ +#define CMN_MODULE_PROCMNG_TSS ( 0x0502 ) /** プロセス管理(TSS管理) */ +#define CMN_MODULE_PROCMNG_SCHED ( 0x0503 ) /** プロセス管理(スケジューラ) */ +#define CMN_MODULE_PROCMNG_TASK ( 0x0504 ) /** プロセス管理(タスク管理) */ +#define CMN_MODULE_PROCMNG_ELF ( 0x0505 ) /** プロセス管理(ELFローダ) */ +#define CMN_MODULE_DEBUG_INIT ( 0x0601 ) /** デバッグ制御(初期化) */ +#define CMN_MODULE_DEBUG_LOG ( 0x0602 ) /** デバッグ制御(ログ管理) */ /** モジュール・サブモジュール数 */ -#define CMN_MODULE_NUM ( 18 ) +#define CMN_MODULE_NUM ( 19 ) /* 処理結果構造体 */ typedef int32_t CmnRet_t; diff --git a/src/kernel/include/Config.h b/src/kernel/include/Config.h new file mode 100644 index 0000000..0781f49 --- /dev/null +++ b/src/kernel/include/Config.h @@ -0,0 +1,26 @@ +/******************************************************************************/ +/* src/kernel/include/Config.h */ +/* 2017/06/04 */ +/* Copyright (C) 2017 Mochi. */ +/******************************************************************************/ +#ifndef CONFIG_H +#define CONFIG_H +/******************************************************************************/ +/* 定義 */ +/******************************************************************************/ +/* 仮想メモリマップ定義 */ +#define CONFIG_MEM_KERNEL_START_ADDR ( 0x00100000 ) /** カーネル領域先頭アドレス */ +#define CONFIG_MEM_KERNEL_STACK_ADDR ( 0x3EFFE000 ) /** カーネル用スタック領域先頭アドレス */ +#define CONFIG_MEM_KERNEL_STACK_SIZE ( 0x00002000 ) /** カーネル用スタック領域サイズ */ +#define CONFIG_MEM_KERNEL_MAP_ADDR1 ( 0x3F000000 ) /** メモリ制御用領域1先頭アドレス */ +#define CONFIG_MEM_KERNEL_MAP_SIZE1 ( 0x00800000 ) /** メモリ制御用領域1サイズ */ +#define CONFIG_MEM_KERNEL_MAP_ADDR2 ( 0x3F800000 ) /** メモリ制御用領域2先頭アドレス */ +#define CONFIG_MEM_KERNEL_MAP_SIZE2 ( 0x00800000 ) /** メモリ制御用領域2サイズ */ +#define CONFIG_MEM_KERNEL_MAP_SIZE ( 0x01000000 ) /** メモリ制御用領域全サイズ */ +#define CONFIG_MEM_TASK_START_ADDR ( 0x40000000 ) /** タスク領域先頭アドレス */ +#define CONFIG_MEM_TASK_STACK_ADDR ( 0xFFFFE000 ) /** タスク用スタック領域先頭アドレス */ +#define CONFIG_MEM_TASK_STACK_SIZE ( 0x00002000 ) /** タスク用スタック領域サイズ */ + + +/******************************************************************************/ +#endif diff --git a/src/kernel/include/MemMng.h b/src/kernel/include/MemMng.h index 82df8e1..5d14ddb 100644 --- a/src/kernel/include/MemMng.h +++ b/src/kernel/include/MemMng.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/include/MemMng.h */ -/* 2017/05/24 */ +/* 2017/06/16 */ /* Copyright (C) 2016-2017 Mochi. */ /******************************************************************************/ #ifndef MEMMNG_H @@ -11,6 +11,7 @@ /* 共通ヘッダ */ #include #include +#include #include /* 外部モジュールヘッダ */ @@ -22,25 +23,25 @@ /* 定義 */ /******************************************************************************/ /* GDT定義 */ -#define MEMMNG_GDT_ENTRY_FULL ( 0 ) /**< GDTエントリ空き無し */ -#define MEMMNG_GDT_ENTRY_MIN ( 1 ) /**< GDTエントリ番号最小値 */ -#define MEMMNG_GDT_ENTRY_MAX ( 9 ) /**< GDTエントリ番号最大値 */ -#define MEMMNG_GDT_ENTRY_NUM \ - ( MEMMNG_GDT_ENTRY_MAX + 1 ) /**< GDTエントリ数 */ +#define MEMMNG_GDT_ENTRY_FULL ( 0 ) /** GDTエントリ空き無し */ +#define MEMMNG_GDT_ENTRY_MIN ( 1 ) /** GDTエントリ番号最小値 */ +#define MEMMNG_GDT_ENTRY_MAX ( 9 ) /** GDTエントリ番号最大値 */ +#define MEMMNG_GDT_ENTRY_NUM \ + ( MEMMNG_GDT_ENTRY_MAX + 1 ) /** GDTエントリ数 */ /* セグメントセレクタ定義 */ -#define MEMMNG_SEGSEL_KERNEL_CODE ( 1 * 8 ) /**< カーネルコードセグメント */ -#define MEMMNG_SEGSEL_KERNEL_DATA ( 2 * 8 ) /**< カーネルデータセグメント */ -#define MEMMNG_SEGSEL_DRIVER_CODE ( 3 * 8 + 1 ) /**< ドライバコードセグメント */ -#define MEMMNG_SEGSEL_DRIVER_DATA ( 4 * 8 + 1 ) /**< ドライバデータセグメント */ -#define MEMMNG_SEGSEL_SERVER_CODE ( 5 * 8 + 2 ) /**< サーバコードセグメント */ -#define MEMMNG_SEGSEL_SERVER_DATA ( 6 * 8 + 2 ) /**< サーバデータセグメント */ -#define MEMMNG_SEGSEL_USER_CODE ( 7 * 8 + 3 ) /**< ユーザコードセグメント */ -#define MEMMNG_SEGSEL_USER_DATA ( 8 * 8 + 3 ) /**< ユーザデータセグメント */ +#define MEMMNG_SEGSEL_KERNEL_CODE ( 1 * 8 ) /** カーネルコードセグメント */ +#define MEMMNG_SEGSEL_KERNEL_DATA ( 2 * 8 ) /** カーネルデータセグメント */ +#define MEMMNG_SEGSEL_DRIVER_CODE ( 3 * 8 + 1 ) /** ドライバコードセグメント */ +#define MEMMNG_SEGSEL_DRIVER_DATA ( 4 * 8 + 1 ) /** ドライバデータセグメント */ +#define MEMMNG_SEGSEL_SERVER_CODE ( 5 * 8 + 2 ) /** サーバコードセグメント */ +#define MEMMNG_SEGSEL_SERVER_DATA ( 6 * 8 + 2 ) /** サーバデータセグメント */ +#define MEMMNG_SEGSEL_USER_CODE ( 7 * 8 + 3 ) /** ユーザコードセグメント */ +#define MEMMNG_SEGSEL_USER_DATA ( 8 * 8 + 3 ) /** ユーザデータセグメント */ /** ページディレクトリID */ -#define MEMMNG_PAGE_DIR_ID_IDLE ( 0 ) /**< アイドルプロセス用PDID */ -#define MEMMNG_PAGE_DIR_ID_MIN ( 1 ) /**< PDID最小値 */ +#define MEMMNG_PAGE_DIR_ID_IDLE ( 0 ) /** アイドルプロセス用PDID */ +#define MEMMNG_PAGE_DIR_ID_MIN ( 1 ) /** PDID最小値 */ /* ページディレクトリ定義 */ #define MEMMNG_PAGE_DIR_NUM PROCMNG_TASK_ID_NUM /** PD管理数 */ @@ -108,7 +109,7 @@ extern CmnRet_t MemMngPageFreeDir( uint32_t id ); extern uint32_t MemMngPageGetDirId( void ); /* ページディレクトリ切替 */ -extern void MemMngPageSwitchDir( uint32_t id ); +extern IA32PagingPDBR_t MemMngPageSwitchDir( uint32_t pageDirId ); /* ページマッピング設定 */ extern CmnRet_t MemMngPageSet( uint32_t dirId, diff --git a/src/kernel/include/ProcMng.h b/src/kernel/include/ProcMng.h index 10b1dd6..15ead9b 100644 --- a/src/kernel/include/ProcMng.h +++ b/src/kernel/include/ProcMng.h @@ -1,11 +1,19 @@ /******************************************************************************/ /* src/kernel/include/ProcMng.h */ -/* 2017/03/03 */ +/* 2017/06/09 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ #ifndef PROCMNG_H #define PROCMNG_H /******************************************************************************/ +/* インクルード */ +/******************************************************************************/ +/* 共通ヘッダ */ +#include +#include + + +/******************************************************************************/ /* 定義 */ /******************************************************************************/ /* タスクID */ @@ -38,7 +46,9 @@ extern void ProcMngSchedExec( void ); /* タスク追加 */ extern uint32_t ProcMngTaskAdd( uint8_t taskType, - void *pEntryPoint ); + void *pAddr, + size_t size ); + /******************************************************************************/ #endif diff --git a/src/kernel/include/hardware/IA32/IA32Instruction.h b/src/kernel/include/hardware/IA32/IA32Instruction.h index d482ee6..0e80339 100644 --- a/src/kernel/include/hardware/IA32/IA32Instruction.h +++ b/src/kernel/include/hardware/IA32/IA32Instruction.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/include/hardware/IA32/IA32Instruction.h */ -/* 2017/03/30 */ +/* 2017/06/16 */ /* Copyright (C) 2016-2017 Mochi. */ /******************************************************************************/ #ifndef IA32_INSTRUCTION_H @@ -667,26 +667,11 @@ static inline void IA32InstructionSetCr0( uint32_t cr0, * @brief cr3レジスタ設定 * @details cr3レジスタにページディレクトリのベースアドレスを設定する。 * - * @param[in] *pBase ベースアドレス - * @param[in] attrPcd ページレベルキャッシュディスエーブルフラグ - * - IA32_PAGING_PCD_ENABLE キャッシング有効 - * - IA32_PAGING_PCD_DISABLE キャッシング無効 - * @param[in] attrPwt ページレベルライトスルーフラグ - * - IA32_PAGING_PWT_WB ライトバックキャッシング - * - IA32_PAGING_PWT_WT ライトスルーキャッシング + * @param[in] pdbr ページディレクトリベースレジスタ */ /******************************************************************************/ -static inline void IA32InstructionSetCr3( void *pBase, - uint32_t attrPcd, - uint32_t attrPwt ) +static inline void IA32InstructionSetCr3( IA32PagingPDBR_t pdbr ) { - IA32PagingPDBR_t pdbr; /* 設定値 */ - - /* 値設定 */ - *( ( uint32_t * ) &pdbr ) = ( ( uint32_t ) pBase ) & 0xFFFFF000; - pdbr.attr_pcd = attrPcd; - pdbr.attr_pwt = attrPwt; - /* cr3レジスタ設定 */ __asm__ __volatile__ ( "mov cr3, %0" : @@ -754,25 +739,33 @@ static inline void IA32InstructionSubEsp( int32_t value ) /** * @brief タスクスイッチ * @details 指定したスタックポインタをespレジスタに、ベースポインタをebpレ - * ジスタに設定し、jmp命令を用いて指定したアドレスを実行する。 + * ジスタに、ページディレクトリベースをpdbrレジスタに設定し、jmp命 + * 令を用いて指定したアドレスを実行する。 * - * @param[in] *pEip 移動先アドレス - * @param[in] *pEsp スタックポインタ - * @param[in] *pEbp ベースポインタ + * @param[in] pdbr ページディレクトリベースレジスタ + * @param[in] *pEip 移動先アドレス + * @param[in] *pEsp スタックポインタ + * @param[in] *pEbp ベースポインタ */ /******************************************************************************/ -static inline void IA32InstructionSwitchTask( void *pEip, - void *pEsp, - void *pEbp ) +static inline void IA32InstructionSwitchTask( IA32PagingPDBR_t pdbr, + void *pEip, + void *pEsp, + void *pEbp ) { /* タスクスイッチ */ __asm__ __volatile__ ( "mov eax, %0\n" - "mov esp, %1\n" - "mov ebp, %2\n" - "jmp eax" + "mov ebx, %1\n" + "mov esp, %2\n" + "mov ebp, %3\n" + "mov cr3, eax\n" + "jmp ebx" : - : "m" ( pEip ), "m" ( pEsp ), "m" ( pEbp ) - : ); + : "a" ( pdbr ), + "m" ( pEip ), + "m" ( pEsp ), + "m" ( pEbp ) + : ); } diff --git a/src/kernel/include/hardware/IA32/IA32Paging.h b/src/kernel/include/hardware/IA32/IA32Paging.h index 60665a6..67a9659 100644 --- a/src/kernel/include/hardware/IA32/IA32Paging.h +++ b/src/kernel/include/hardware/IA32/IA32Paging.h @@ -1,6 +1,6 @@ /******************************************************************************/ /* src/kernel/include/hardware/IA32/IA32Paging.h */ -/* 2017/03/30 */ +/* 2017/06/16 */ /* Copyright (C) 2017 Mochi. */ /******************************************************************************/ #ifndef IA32_PAGING_H @@ -14,20 +14,29 @@ /******************************************************************************/ /* 定義 */ /******************************************************************************/ +/** PDBR設定マクロ */ +#define IA32_PAGING_SET_PDBR( _PDBR, _PBASE, _PCD, _PWT ) \ + { \ + *( ( uint32_t * ) &( _PDBR ) ) = \ + ( ( uint32_t ) ( _PBASE ) ) & 0xFFFFF000; \ + ( _PDBR ).attr_pcd = ( _PCD ); \ + ( _PDBR ).attr_pwt = ( _PWT ); \ + } + /** ページディレクトリエントリインデックス取得マクロ */ -#define IA32_PAGING_GET_PDE_IDX( _PADDR ) \ +#define IA32_PAGING_GET_PDE_IDX( _PADDR ) \ ( ( ( ( uint32_t ) ( _PADDR ) ) >> 22 ) & 0x3FF ) /** ページテーブルエントリインデックス取得マクロ */ -#define IA32_PAGING_GET_PTE_IDX( _PADDR ) \ +#define IA32_PAGING_GET_PTE_IDX( _PADDR ) \ ( ( ( ( uint32_t ) ( _PADDR ) ) >> 12 ) & 0x3FF ) /** ページテーブル・ページベースアドレス設定マクロ */ -#define IA32_PAGING_SET_BASE( _PENTRY, _PBASE ) \ - ( *( ( uint32_t * ) ( _PENTRY ) ) = \ - ( ( ( uint32_t ) ( _PBASE ) ) & 0xFFFFF000 ) | \ +#define IA32_PAGING_SET_BASE( _PENTRY, _PBASE ) \ + ( *( ( uint32_t * ) ( _PENTRY ) ) = \ + ( ( ( uint32_t ) ( _PBASE ) ) & 0xFFFFF000 ) | \ ( *( ( uint32_t * ) ( _PENTRY ) ) & 0x00000FFF ) ) /** ページテーブル・ページベースアドレス取得マクロ */ -#define IA32_PAGING_GET_BASE( _PENTRY ) \ +#define IA32_PAGING_GET_BASE( _PENTRY ) \ ( ( void * ) ( *( ( uint32_t * ) ( _PENTRY ) ) & 0xFFFFF000 ) ) /* ページテーブル・ページ存在フラグ */ @@ -76,8 +85,8 @@ /** PDBR */ typedef struct { uint32_t reserved2:3; /**< 予約済み */ - uint32_t attr_pwt:1; /**< ページレベルライトスルーフラグ */ - uint32_t attr_pcd:1; /**< ページレベルキャッシュディスエーブルフラグ */ + uint32_t attr_pwt :1; /**< ページレベルライトスルーフラグ */ + uint32_t attr_pcd :1; /**< ページレベルキャッシュディスエーブルフラグ */ uint32_t reserved1:7; /**< 予約済み */ uint32_t base :20; /**< ページディレクトリベースアドレス */ } IA32PagingPDBR_t; -- 2.11.0