OSDN Git Service

カーネルイメージ作成ツール追加
authorMochi <master.c.mochi@gmail.com>
Sun, 16 Jul 2017 15:45:01 +0000 (00:45 +0900)
committerMochi <master.c.mochi@gmail.com>
Sun, 16 Jul 2017 15:45:01 +0000 (00:45 +0900)
src/include/kernel/MochiKernel.h
src/tools/Makefile
src/tools/makedisk/makedisk.c
src/tools/makeimg/Makefile [new file with mode: 0644]
src/tools/makeimg/makeimg.c [new file with mode: 0644]

index 45d5ce9..92ee05c 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/include/kernel/MochiKernel.h                                           */
-/*                                                                 2017/07/11 */
+/*                                                                 2017/07/16 */
 /* Copyright (C) 2017 Mochi                                                   */
 /******************************************************************************/
 #ifndef _MOCHI_KERNEL_H_
 #define MOCHIKERNEL_MEMORY_TYPE_ACPI_NVS  ( 0x04 )  /** ACPI NVSメモリ領域 */
 #define MOCHIKERNEL_MEMORY_TYPE_KERNEL    ( 0x05 )  /** MochiKernel領域    */
 
+/* プロセスタイプ */
+#define MOCHIKERNEL_PROCESS_TYPE_NONE     ( 0x00 )  /** プロセスタイプ無し */
+#define MOCHIKERNEL_PROCESS_TYPE_KERNEL   ( 0x01 )  /** カーネルプロセス   */
+#define MOCHIKERNEL_PROCESS_TYPE_DRIVER   ( 0x02 )  /** ドライバプロセス   */
+#define MOCHIKERNEL_PROCESS_TYPE_SERVER   ( 0x03 )  /** サーバプロセス     */
+#define MOCHIKERNEL_PROCESS_TYPE_USER     ( 0x04 )  /** ユーザプロセス     */
+
 /** メモリマップ */
 typedef struct {
     void     *pAddr;    /**< 先頭アドレス */
@@ -33,6 +40,14 @@ typedef struct {
     uint32_t type;      /**< メモリタイプ */
 } MochiKernelMemoryMap_t;
 
+/** カーネルイメージヘッダ */
+typedef struct {
+    char     fileName[ 256 ];   /**< ファイル名     */
+    uint32_t fileSize;          /**< ファイルサイズ */
+    uint8_t  fileType;          /**< ファイルタイプ */
+    uint8_t  reserved[ 251 ];   /**< 予約済み領域   */
+} MochiKernelImgHdr_t;
+
 
 /******************************************************************************/
 #endif
index c73f847..753e6b4 100644 (file)
@@ -1,6 +1,6 @@
 #******************************************************************************#
 #* src/tools/Makefile                                                         *#
-#*                                                                 2017/06/29 *#
+#*                                                                 2017/07/11 *#
 #* Copyright (C) 2017 Mochi.                                                  *#
 #******************************************************************************#
 #******************************************************************************#
@@ -10,7 +10,8 @@
 CUR_DIR  = tools
 
 # サブディレクトリ
-SUB_DIRS = makedisk
+SUB_DIRS = makedisk \
+           makeimg
 
 
 #******************************************************************************#
index 9d758fd..afc7c78 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************/
 /* src/tools/makedisk/makedisk.c                                              */
-/*                                                                 2017/07/02 */
+/*                                                                 2017/07/11 */
 /* Copyright (C) 2017 Mochi.                                                  */
 /******************************************************************************/
 /******************************************************************************/
@@ -166,7 +166,6 @@ int main( int  argNum,
     chs_t    chs;           /* CHSアドレス                        */
     off_t    offset;        /* オフセット                         */
     int32_t  size;          /* 書込みサイズ                       */
-    uint32_t aaaaacylinder;      /* シリンダ                           */
     
     /* 初期化 */
     end = 0;
diff --git a/src/tools/makeimg/Makefile b/src/tools/makeimg/Makefile
new file mode 100644 (file)
index 0000000..17b437e
--- /dev/null
@@ -0,0 +1,57 @@
+#******************************************************************************#
+#* src/tools/makeimg/Makefile                                                 *#
+#*                                                                 2017/07/16 *#
+#* Copyright (C) 2017 Mochi.                                                  *#
+#******************************************************************************#
+#******************************************************************************#
+#* マクロ設定                                                                 *#
+#******************************************************************************#
+# ベースディレクトリsrc/からの相対パス
+CUR_DIR   = tools/makeimg
+
+# バイナリ名
+TOOL_NAME = makeimg
+
+# ソースコード
+SRCS      = makeimg.c
+
+# Cフラグ
+CFLAGS    = -include../../include/kernel/MochiKernel.h   \
+            -include../../include/MLib/Basic/MLibBasic.h
+
+
+#******************************************************************************#
+#* 自動設定マクロ                                                             *#
+#******************************************************************************#
+# ベースディレクトリパス
+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/makeimg/makeimg.c b/src/tools/makeimg/makeimg.c
new file mode 100644 (file)
index 0000000..55e965f
--- /dev/null
@@ -0,0 +1,436 @@
+/******************************************************************************/
+/* src/tools/makeimg/makeimg.c                                                */
+/*                                                                 2017/07/16 */
+/* Copyright (C) 2017 Mochi.                                                  */
+/******************************************************************************/
+/******************************************************************************/
+/* インクルード                                                               */
+/******************************************************************************/
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+/******************************************************************************/
+/* 定義                                                                       */
+/******************************************************************************/
+/** アボートマクロ */
+#define ABORT( ... )                    \
+    {                                   \
+        /* エラー出力 */                \
+        fprintf( stderr, __VA_ARGS__ ); \
+        fprintf( stderr, "\n" );        \
+                                        \
+        /* USAGE出力 */                 \
+        printUsage( EXIT_FAILURE );     \
+    }
+
+/* 読込バッファサイズ */
+#define BUFFER_SIZE ( 512 )
+
+
+/******************************************************************************/
+/* ローカル関数プロトタイプ宣言                                               */
+/******************************************************************************/
+/* ファイル追加 */
+static void addFile( int  imgFd,
+                     char *pPath );
+
+/* オプションチェック */
+static void checkOptions( int32_t argNum,
+                          char    *pArg[] );
+
+/* ファイル名取得 */
+static void getFileName( char     *pFileName,
+                         char     *pFilePath,
+                         uint32_t length      );
+
+/* USAGE出力 */
+static void printUsage( int status );
+
+
+/******************************************************************************/
+/* グローバル変数定義                                                         */
+/******************************************************************************/
+/* オプション */
+char    *gpImgPath;     /* 出力先イメージファイルパス */
+uint8_t gFileType;      /* 入力ファイルタイプ         */
+
+
+/******************************************************************************/
+/* グローバル関数定義                                                         */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       makeimg
+ * @details     カーネルイメージを作成する。
+ * 
+ * param[in]    argNum  引数の数
+ * param[in]    *pArg[] 引数
+ * 
+ * retval       EXIT_SUCCESS 正常終了
+ * retval       EXIT_FAILURE 異常終了
+ */
+/******************************************************************************/
+int main( int  argNum,
+          char *pArg[] )
+{
+    int imgFd;  /* イメージファイルディスクリプタ */
+    int flags;  /* オープンフラグ                 */
+    
+    /* オプションチェック */
+    checkOptions( argNum, pArg );
+    
+    /* ファイルタイプチェック */
+    if ( gFileType == MOCHIKERNEL_PROCESS_TYPE_KERNEL ) {
+        /* カーネル */
+        
+        /* オープンフラグ設定 */
+        flags = O_RDWR | O_CREAT | O_TRUNC;
+        
+    } else {
+        /* カーネル以外 */
+        
+        /* オープンフラグ設定 */
+        flags = O_RDWR;
+    }
+    
+    /* イメージオープン */
+    imgFd = open( gpImgPath,
+                  flags,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH );
+    
+    /* オープン結果判定 */
+    if ( imgFd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               gpImgPath,
+               errno );
+    }
+    
+    /* ファイル書込み */
+    for ( ; optind < argNum; optind++ ) {
+        addFile( imgFd, pArg[ optind ] );
+    }
+    
+    /* 仮想ディスククローズ */
+    close( imgFd );
+    
+    /* 正常終了 */
+    return EXIT_SUCCESS;
+}
+
+
+/******************************************************************************/
+/* ローカル関数定義                                                           */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * @brief       ファイル追加
+ * @details     イメージファイルにファイルを追加する
+ * 
+ * @param[in]   imgFd  イメージファイルディスクリプタ
+ * @param[in]   *pPath ファイルパス
+ */
+/******************************************************************************/
+static void addFile( int  imgFd,
+                     char *pPath )
+{
+    int                 fd;                     /* ファイルディスクリプタ */
+    off_t               offset;                 /* ファイルオフセット     */
+    off_t               headerOffset;           /* ヘッダオフセット       */
+    ssize_t             readSize;               /* 読込みサイズ           */
+    ssize_t             writeSize;              /* 書込みサイズ           */
+    uint8_t             buffer[ BUFFER_SIZE ];  /* バッファ               */
+    uint32_t            size;                   /* ファイルサイズ         */
+    MochiKernelImgHdr_t header;                 /* ファイルヘッダ         */
+    
+    /* 初期化 */
+    size = 0;
+    memset( &header, 0, sizeof ( MochiKernelImgHdr_t ) );
+    
+    /* イメージファイルシーク */
+    offset = lseek( imgFd, 512, SEEK_END );
+    
+    /* シーク結果判定 */
+    if ( ( ( ( int32_t ) offset       ) <  0 ) &&
+         ( ( ( int32_t ) offset % 512 ) != 0 )    ) {
+        /* 失敗または異常 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the image. ret=%d, errno%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* ヘッダオフセット設定 */
+    headerOffset = offset - ( off_t ) sizeof ( MochiKernelImgHdr_t );
+    
+    /* ファイルオープン */
+    fd = open( pPath, O_RDONLY );
+    
+    /* オープン結果判定 */
+    if ( fd == -1 ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't open %s. errno=%d.\n",
+               __LINE__,
+               pPath,
+               errno );
+    }
+    
+    /* バッファサイズ毎に繰り返し */
+    do {
+        /* バッファ初期化 */
+        memset( buffer, 0, BUFFER_SIZE );
+        
+        /* ファイル読込 */
+        readSize = read( fd, buffer, BUFFER_SIZE );
+        
+        /* 読込結果判定 */
+        if ( readSize == -1 ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't read from %s. errno=%d.\n",
+                   __LINE__,
+                   pPath,
+                   errno );
+            
+        } else if ( readSize == 0 ) {
+            /* EOF */
+            
+            break;
+        }
+        
+        /* ファイルサイズ更新 */
+        size += ( uint32_t ) readSize;
+        
+        /* 書込み */
+        writeSize = write( imgFd, buffer, MLIB_BASIC_ALIGN( readSize, 512 ) );
+        
+        /* 書込み結果判定 */
+        if ( writeSize != MLIB_BASIC_ALIGN( readSize, 512 ) ) {
+            /* 失敗 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Can't write %s. ret=%d, errno=%d.\n",
+                   __LINE__,
+                   pPath,
+                   ( int32_t ) writeSize,
+                   errno );
+        }
+        
+    } while ( readSize == BUFFER_SIZE );
+    
+    /* ファイルヘッダ設定 */
+    getFileName( header.fileName, pPath, sizeof ( header.fileName ) - 1 );
+    header.fileSize = size;
+    header.fileType = gFileType;
+    
+    /* イメージファイルシーク */
+    offset = lseek( imgFd, headerOffset, SEEK_SET );
+    
+    /* シーク結果判定 */
+    if ( offset != headerOffset ) {
+        /* 失敗または異常 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't seek at the image. ret=%d, errno%d.\n",
+               __LINE__,
+               ( int32_t ) offset,
+               errno );
+    }
+    
+    /* ファイルヘッダ書込み */
+    writeSize = write( imgFd, &header, sizeof ( MochiKernelImgHdr_t ) );
+    
+    /* 書込み結果判定 */
+    if ( writeSize != sizeof ( MochiKernelImgHdr_t ) ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't write %s. ret=%d, errno=%d.\n",
+               __LINE__,
+               pPath,
+               ( int32_t ) writeSize,
+               errno );
+    }
+    
+    /* ファイルクローズ */
+    close( fd );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       オプションチェック
+ * @details     オプションが許容可能な値かチェックする。
+ * 
+ * @param[in]   argNum  引数の数
+ * @param[in]   *pArg[] 引数
+ */
+/******************************************************************************/
+static void checkOptions( int32_t argNum,
+                          char    *pArg[] )
+{
+    char opt;   /* オプション文字 */
+    
+    /* 初期化 */
+    gpImgPath = NULL;
+    gFileType = MOCHIKERNEL_PROCESS_TYPE_NONE;
+    
+    /* オプションが無くなるまで繰り返し */
+    while ( true ) {
+        /* オプション取得 */
+        opt = getopt( argNum, pArg, "o:KDSUh" );
+        
+        /* 取得結果判定 */
+        if ( opt == -1 ) {
+            /* オプション無し */
+            break;
+            
+        } else if ( opt == 'o' ) {
+            /* 出力先ファイルパス */
+            gpImgPath = optarg;
+            
+        } else if ( opt == 'K' ) {
+            /* カーネルファイル入力 */
+            gFileType = MOCHIKERNEL_PROCESS_TYPE_KERNEL;
+            
+        } else if ( opt == 'D' ) {
+            /* ドライバファイル入力 */
+            gFileType = MOCHIKERNEL_PROCESS_TYPE_DRIVER;
+            
+        } else if ( opt == 'S' ) {
+            /* サーバファイル入力 */
+            gFileType = MOCHIKERNEL_PROCESS_TYPE_SERVER;
+            
+        } else if ( opt == 'U' ) {
+            /* ユーザファイル入力 */
+            gFileType = MOCHIKERNEL_PROCESS_TYPE_USER;
+            
+        } else if ( opt == 'h' ) {
+            /* ヘルプ */
+            
+            /* USAGE出力して終了 */
+            printUsage( EXIT_SUCCESS );
+            
+        } else {
+            /* 他 */
+            
+            /* アボート */
+            ABORT( "ERROR(%04u): Unknown option!\n", __LINE__ );
+        }
+    }
+    
+    /* 出力先ファイルパス設定チェック */
+    if ( gpImgPath == NULL ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No '-o' option!\n", __LINE__ );
+    }
+    
+    /* 入力ファイルタイプ設定チェック */
+    if ( gFileType == MOCHIKERNEL_PROCESS_TYPE_NONE ) {
+        /* 未設定 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): No set file type! ( '-K', '-D', '-S' or '-U' )\n",
+               __LINE__ );
+    }
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       ファイル名取得
+ * @details     ファイルパスからファイル名を取得する。
+ * 
+ * @param[out]  *pFileName ファイル名
+ * @param[in]   *pFilePath ファイルパス
+ * @param[in]   length     ファイル名長
+ */
+/******************************************************************************/
+static void getFileName( char     *pFileName,
+                         char     *pFilePath,
+                         uint32_t length      )
+{
+    char *pStr1;
+    char *pStr2;
+    
+    /* 初期化 */
+    pStr1 = pFilePath;
+    pStr2 = NULL;
+    
+    /* 最終分離符検索 */
+    do {
+        /* 分離符位置バックアップ */
+        pStr2 = pStr1;
+        pStr2++;
+        
+        /* 分離符検索 */
+        pStr1 = strstr( pStr2, "/" );
+        
+    } while ( pStr1 != NULL );
+    
+    /* 検索結果判定 */
+    if ( pStr2 == NULL ) {
+        /* 失敗 */
+        
+        /* アボート */
+        ABORT( "ERROR(%04u): Can't search!", __LINE__ );
+    }
+    
+    /* ファイル名格納 */
+    strncpy( pFileName, pStr2, length );
+    
+    return;
+}
+
+
+/******************************************************************************/
+/**
+ * @brief       USAGE出力
+ * @details     USAGEを出力しプログラムを終了する。
+ * 
+ * @param[in]   status 終了ステータス
+ */
+/******************************************************************************/
+static void printUsage( int status )
+{
+    /* USAGE出力 */
+    fprintf( stderr, "USAGE: makedisk -o [FILE] { -K | -D | -S | -U } [FILE]...\n"              );
+    fprintf( stderr, "\n"                                                                       );
+    fprintf( stderr, "Option:\n"                                                                );
+    fprintf( stderr, "  -o FILE specify the output FILE that is a kernel image.\n"              );
+    fprintf( stderr, "  -K FILE specify the input FILE type that is a kernel binary.\n"         );
+    fprintf( stderr, "  -D FILE specify the input FILE type that is a driver process binary.\n" );
+    fprintf( stderr, "  -S FILE specify the input FILE type that is a server process binary.\n" );
+    fprintf( stderr, "  -U FILE specify the input FILE type that is a user process binary.\n"   );
+    fprintf( stderr, "  -h      print help.\n"                                                  );
+    
+    /* 終了 */
+    exit( status );
+}
+
+
+/******************************************************************************/