Visual Studio で日中韓台文字表示 UEFI アプリ作成のメモ

以下の UEFI アプリのプロジェクト設定やソースコードに関する補足情報のメモです。

UEFI_FreeType_MSVC
https://github.com/tenpoku1000/UEFI_FreeType_MSVC

## 各プロジェクト共通の設定

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.1

    「全般→SDLチェック」を空欄に設定

以下の警告が出力されなくなります。  

warning D9025: '/sdl' より '/GS-' が優先されます。

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.2

    最適化→組み込み関数を使用する→いいえ

以下のエラーを回避し、musl の関数が使用されるようになります。  
error C2169: 'memcmp' : 組み込み関数は定義できません。

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.3

    コード生成→基本ランタイムチェック → 規定値

以下のエラーを回避します。  

error LNK2001: 外部シンボル "__RTC_InitBase" は未解決です。
error LNK2001: 外部シンボル "__RTC_Shutdown" は未解決です。

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.4

		セキュリティチェック → セキュリティチェックを無効にします。(/GS-)

以下のエラーを回避します。  

error LNK2019: 未解決の外部シンボル __RTC_CheckEsp が関数 XXXXXX で参照されました。

## musl 以外に共通のプロジェクト設定(2016/09/19 追記)

### プロジェクトのプロパティ→構成プロパティ→C/C++

    プリプロセッサ→標準インクルード パスの無視→はい
 
musl に intrinsic を利用する修正をしているため、musl 以外のプロジェクトに対してのみ、この設定を行います。

## gnu-efi, freetype, musl 共通のプロジェクト設定

### プロジェクトのプロパティ→構成プロパティ→全般

    構成の種類→スタティック ライブラリ(.lib)
    ターゲットの拡張子→.lib

### プロジェクトのプロパティ→構成プロパティ→ライブラリアン→全般

    すべての既定のライブラリの無視→はい(/NODEFAULTLIB)
    対象コンピューター→MachineX64(/MACHINE:X64)
    サブシステム→EFI アプリケーション(/SUBSYSTEM=EFI_APPLICATION)

### 参考資料

/SUBSYSTEM (サブシステムの指定)
https://msdn.microsoft.com/ja-jp/library/fcc1zstk.aspx

## UEFI_FreeType_MSVC プロジェクトの設定

### プロジェクトのプロパティ→構成プロパティ→全般

    構成の種類→ダイナミック ライブラリ(.dll)
    ターゲットの拡張子→.efi

### 「プロジェクトのプロパティ→構成プロパティ→リンカー」No.1

    入力→すべての既定のライブラリの無視→はい(/NODEFAULTLIB)
    システム→サブシステム→EFI アプリケーション(/SUBSYSTEM=EFI_APPLICATION)
    詳細設定→エントリポイント→efi_main
    詳細設定→対象コンピューター→MachineX64(/MACHINE:X64)

### 「プロジェクトのプロパティ→構成プロパティ→リンカー」No.2

    詳細設定→ランダム化されたベースアドレス→いいえ(/DYNAMICBASE:NO)

/DYNAMICBASE:NO は、以下のリンク・エラーを回避する設定です。  

fatal error LNK1295: '/DYNAMICBASE' は '/SUBSYSTEM:EFI_APPLICATION' の指定と互換性がありません。'/DYNAMICBASE' なしでリンクしてください。

### 「プロジェクトのプロパティ→構成プロパティ→リンカー」No.3

    詳細設定→データ実行防止(DEP)→いいえ(/NXCOMPAT:NO)

/NXCOMPAT:NO は、以下のリンク・エラーを回避する設定です。  

fatal error LNK1295: '/NXCOMPAT' は '/SUBSYSTEM:EFI_APPLICATION' の指定と互換性がありません。'/NXCOMPAT' なしでリンクしてください。

### 「プロジェクトのプロパティ→構成プロパティ→リンカー」No.4

    マニフェストファイル→ユーザーアカウント制御(UAC)を有効にする→いいえ(/MANIFESTUAC:NO)

/MANIFESTUAC:NO は、以下のリンク・エラーを回避する設定です。  

LINK : fatal error LNK1295: '/MANIFESTUAC' は '//SUBSYSTEM:EFI_APPLICATION' の指定と互換性がありません。'/MANIFESTUAC' なしでリンクしてください。

## gnu-efi プロジェクトの設定(2016/08/15 追記)

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.5

    「詳細設定→指定の警告を無視する」に 4133 を設定

以下の警告が出力されなくなります。  

C4133: '初期化中': 'unsigned short [8]' と 'WCHAR *' の間で型に互換性がありません。

## gnu-efi と、gnu-efi に依存するプロジェクトの設定(2016/08/15 追記)

### 「プロジェクトのプロパティ→構成プロパティ→C/C++」No.6

    「詳細設定→指定の警告を無視する」に 4091 を設定

以下の警告が出力されなくなります。  

C4091: 'typedef ': 変数が何も宣言されていないときは、'_EFI_PCI_IO' の左辺を無視します。

## freetype プロジェクトの設定

### afscript.h, afblue.c ファイルを BOM 付き UTF-8 に変換

    src\lib\external\FreeType\freetype\src\autofit\afscript.h
    src\lib\external\FreeType\freetype\src\autofit\afblue.c

以下の警告が出力されなくなります。

warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。

### プロジェクトのプロパティ→構成プロパティ→C/C++

    コマンドライン→追加のオプション→/Gs40960

__chkstk 関数呼び出しを生成しないようにするため、/Gs に与える数値を大きく設定することで、以下のエラーを回避します。

error LNK2019: 未解決の外部シンボル __chkstk が関数 XXXXXX で参照されました。

### 参考資料

/Gs (スタック チェック呼び出しの制御)
https://msdn.microsoft.com/ja-jp/library/9598wk25.aspx

## gnu-efi を UEFI GOP(Graphics Output Protocol)対応にする修正

gnu-efi 3.0w では GOP 対応が完全ではありませんでした。以下のファイルに以下のコードを追加する必要がありました。

    src\lib\external\BSD\gnu-efi\inc\efilib.h

    extern EFI_GUID GraphicsOutputProtocol;

## musl に関する情報

### Autotools を実行し、必要なヘッダファイルを生成

MinGW-w64 と MinGW をインストールして bash から以下のコマンドを投入すると、include/bits, include/bits/alltypes.h が出来ます。arch/x86_64/bits にあるファイルを修正したら、configure の前に include/bits を削除してください。    

    ./configure
    make include/bits/alltypes.h

PATH 環境変数には、MinGW-w64 直下の bin と MinGW の MSYS の bin を登録してください。Bash on Ubuntu on Windows をインストールしている環境では、一時的にシステム環境変数の PATH の先頭に MSYS の bin を登録すると、MSYS の bash が使えるようになります。mingw-w64-install.exe の Settings 画面では以下のように入力します。

    Architecture: x86_64
    Threads: win32
    Exception: seh

* MinGW-w64 http://sourceforge.net/projects/mingw-w64/
* MinGW http://sourceforge.net/projects/mingw/

### 浮動小数点数処理用変数 _fltused を定義

libc.c ファイルに変数 _fltused を追加します。

    src\lib\external\MIT\musl\src\internal\libc.c

    int _fltused = 1;

以下のリンク・エラーを回避します。

error LNK2001: 外部シンボル "_fltused" は未解決です。

### calloc 関数で確保したバッファの末尾がゼロ・クリアされない現象の修正

musl 1.1.5 の calloc 関数内の malloc 関数呼び出し後の処理を
memset 関数呼び出しに置き換え、バッファの末尾がゼロ・クリアされるように修正します。

    src\lib\external\MIT\musl\src\malloc\calloc.c

    memset(p, 0, n);

### Linux システムコール呼び出しを UEFI 関数呼び出しに置き換えが必要な箇所

    src\lib\external\MIT\musl\src\malloc\malloc.c
    src\lib\external\MIT\musl\src\stdio\__fdopen.c
    src\lib\external\MIT\musl\src\stdio\__stdio_close.c
    src\lib\external\MIT\musl\src\stdio\__stdio_read.c
    src\lib\external\MIT\musl\src\stdio\__stdio_seek.c
    src\lib\external\MIT\musl\src\stdio\__stdio_write.c

### setjmp, longjmp を MS-ABI 対応に修正

asm ファイルは BOM 無し UTF-8 です。BOM が付いているとエラーになります。

    src\lib\external\MIT\musl\src\setjmp\x86_64\longjmp.s
    src\lib\external\MIT\musl\src\setjmp\x86_64\setjmp.s

    src\lib\external\MIT\musl\src\setjmp\x86_64\longjmp.asm
    src\lib\external\MIT\musl\src\setjmp\x86_64\setjmp.asm
    src\lib\external\MIT\musl\include\bits\setjmp.h