gonzui


Format: Advanced Search

t2ex/doc/ja/impl-t2exl.txtbare sourcepermlink (0.05 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.0.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by T-Engine Forum at 2015/2/27.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: ==============================================================================
   16:                T-Engineリファレンスボード用 T2EX実装仕様書
   17: ==============================================================================
   18: 
   19: ------------------------------------------------------------------------------
   20: 1. 概要
   21: ------------------------------------------------------------------------------
   22: 
   23: 本書は、T-Engine リファレンスボード上で動作する T-Kernel 2.0 Extension (T2EX)
   24: の実装に関する設定やリソースに関する詳細や制限事項を記述した仕様書である。
   25: 
   26: 
   27: ------------------------------------------------------------------------------
   28: 2. T-Kernel 2.0 リファレンス実装との差分
   29: ------------------------------------------------------------------------------
   30: 
   31:       T2EXの実装は T-Kernel 2.0 のリファレンス実装をベースとし、追加を行うことを
   32:       基本として作られているが、一部 T-Kernel 2.0 リファレンス実装に対して修正を
   33:       加えている。
   34: 
   35:       具体的には、以下の点について T-Kernel 2.0 リファレンス実装に対する変更が行
   36:       われている。
   37: 
   38:         - ディスパッチャ (${BD}/kernel/sysdepend_t2ex/cpu/em1d/cpu_support.S)
   39:                 プロセッサの排他的レジスタロード/ストア命令(ldrexおよびstrex)の
   40:                 利用のために、ディスパッチ時に排他をクリア(clrex)する処理を追加。
   41: 
   42:         - メモリ管理機能 (${BD}/kernel/extension/memory/t2ex)
   43:                 詳細については第3節に示す。
   44: 
   45: 
   46: ------------------------------------------------------------------------------
   47: 3. メモリ保護機能
   48: ------------------------------------------------------------------------------
   49: 
   50: 3.1 基本的な設定項目
   51: 
   52:       T2EXのメモリ管理機能の基本的な設定は、ソースプログラム中の以下のファイルに
   53:       含まれる設定を書き換えることで行うことができる。
   54: 
   55:               kernel/sysmain/build_t2ex/tef_em1d/Makefile
   56: 
   57:       以下のようなパラメータを設定することが可能である。
   58: 
   59:          - T2EX_MM
   60:               利用するメモリ管理機能名のサフィックス
   61:               _t2ex : T2EX標準のメモリ保護機能を用いる
   62:               (空)  : T-Kernel 2.0標準のメモリ管理機能(メモリ保護なし)を用いる
   63: 
   64:          - T2EX_MM_USE_TASKEXCEPTION
   65:               メモリ保護違反時の処理方法の指定
   66:               1 : TaskMemFaultHdr() を利用する標準構成を利用する
   67:               0 : TaskMemFaultHdr() を利用しない簡易構成を利用する
   68: 
   69:          - T2EX_MM_USE_DEFAULT_FAULT_HANDLER
   70:               保護違反処理例外ハンドラの定義位置の指定
   71:               1 : T2EXシステムコード内部で定義されたハンドラを利用する
   72:               0 : ユーザアプリケーション側で定義されたハンドラを利用する
   73: 
   74:       3.2から3.6までの各節では、T2EX_MM を _t2ex とした場合の構成について述べる。
   75:       T2EX_MM を空とする場合、すなわちT2EXのメモリ保護機能を利用しない場合の設定に
   76:       ついては、3.7節で述べる。
   77: 
   78: 3.2 MMUの設定
   79: 
   80:       以下のように設定されており、T-Kernel 2.0リファレンス実装と共通である。
   81:       この設定は、システム起動時に T-Monitor により設定され、以後変更されない
   82:       (変更してはならない)。
   83: 
   84:    (a) SCTLR.AFE [29] = 1
   85: 
   86:       ページテーブルのアクセスフラグを有効にする。
   87: 
   88:    (b) SCTLR.TRE [28] = 1
   89: 
   90:       メモリ属性 TEX の再マップを有効にする。
   91: 
   92:    (c) PRRR = 0x000a8aa4
   93: 
   94:    (d) NMRR = 0x44e048e0
   95: 
   96:       メモリ属性の再マップを、以下のように割り当てる。
   97: 
   98:       TEX[0] C B      メモリタイプ    内部キャッシュ  外部キャッシュ
   99:            0 0 0      Strongly-order  None            None
  100:            0 0 1      Device          None            None
  101:            0 1 0      Normal          WT-NA           WT-NA
  102:            0 1 1      Normal          WB-NA           WB-NA
  103:            1 0 0      Normal          None            None
  104:            1 0 1      Normal          WT-NA           WB-A
  105:            1 1 0      (未使用)
  106:            1 1 1      Normal          WB-A            WB-A
  107: 
  108:               WT-NA   Write-through, no allocate on write
  109:               WB-NA   Write-back, no allocate on write
  110:               WB-A    Write-back, allocate on write
  111: 
  112: 3.3 メモリマップ
  113: 
  114:       以下の通りとなっており、T-Kernel 2.0リファレンス実装とおおむね共通である。
  115: 
  116:           論理アドレス                         モード
  117:            0x00000000 +=======================+       --
  118:                       |タスク固有空間         |       |  仮想メモリ (予約)
  119:            0x10000000 +=======================+       --
  120:                       |周辺デバイス           | S D RW-
  121:                       |(未使用領域含む)       |
  122:            0x30000000 +-----------------------+       --
  123:                       |RAM             (64MB) |       |  保護メモリ領域
  124:                       |(未使用領域含む)       |
  125:            0x40000000 +-----------------------+       --
  126:                       |周辺デバイス           | S D RW-
  127:                       |(未使用領域含む)       |         物理アドレス
  128:            0x70000000 +-----------------------+       -- 0x00000000
  129:                       |ROM             (32MB) | S C R-X |  NOR Flash を写像(*1)
  130:            0x72000000 +-----------------------+       -- 0x02000000
  131:                       |(予約)                 |
  132:            0x80000000 +=======================+       --
  133:                       |プログラムマップ用     |       ↑
  134:            0x90000000 +-----------------------+       |  仮想メモリ (予約)
  135:                       |メモリマップ用         |       ↓
  136:            0xa0000000 +=======================+       --
  137:                       |内蔵 SRAM      (128KB) | S N RWX
  138:                       |(未使用領域含む)       |
  139:            0xb0000000 +-----------------------+
  140:                       |周辺デバイス           | S D RW-
  141:                       |(未使用領域含む)       |
  142:            0xd0000000 +=======================+       --
  143:                       |共有メモリ空間         |       |  仮想メモリ (予約)
  144:            0xf0000000 +=======================+       --
  145:                       |内蔵 Boot ROM          | S N R--
  146:                       |(未使用領域含む)       |
  147:            0xffffffff +-----------------------+
  148: 
  149:       モード
  150:         保護レベル属性
  151:           S   システムレベル (ユーザレベルからのアクセス不可)
  152:           U   ユーザレベル (システムレベル・ユーザレベルからアクセス可能)
  153: 
  154:         メモリタイプ/キャッシュ属性
  155:           C   キャッシュ ON   Normal memory / Write-back cache, Write allocate
  156:           N   キャッシュ OFF  Normal memory / Non-cacheable
  157:           D   デバイス        Device memory / Non-cacheable
  158: 
  159:         アクセス属性 ( - はその属性がオフ)
  160:           R   リード可
  161:           W   ライト可
  162:           X   プログラム実行可
  163: 
  164:       ・各領域のドメインはすべて 0 である。
  165: 
  166:       ・保護メモリ領域となっている領域はT2EXメモリ保護機能によって管理される
  167:         領域であり、ページ単位(4KB)でモードの指定が行われる。
  168:         保護メモリ領域以外の領域はいずれもセクション単位(1MB)でマッピング
  169:         およびモードの指定が行われる。
  170: 
  171:       ・仮想メモリとなっている領域は本実装では使用されず、予約されている。
  172:         未割り当て領域として設定されており、アクセス不可となっている。
  173: 
  174:       ・保護メモリおよび仮想メモリ以外の領域は、論理アドレス=物理アドレスとして
  175:         マッピングされ、マッピング・モードのいずれも動的に変化しない。
  176: 
  177:            (*1) ただし、タスク固有空間に隠れてしまう NOR Flash の領域は、論理
  178:                 アドレス=物理アドレスとはならず、上記メモリマップのように移動
  179:                 してマッピングする。このマッピングは動的に変化しない。
  180: 
  181:         本書中のアドレスは、特に記述がない限り論理アドレスで表記されている。
  182: 
  183:       ・内蔵 SRAM および内蔵 Boot ROM は、システム起動時(ブート時)に使用される
  184:         が、システム起動後は使用されず、OS による管理もされない。
  185:         システム起動後、内蔵 SRAM は、任意の用途に使用可能である。
  186: 
  187:       ・保護メモリ領域のうち、tk_get_smb() や malloc() 等の動的メモリ割り当て
  188:         APIコールや、システム内部の動的なメモリ割り当てに用いられる領域を動的
  189:         割り当て領域と呼ぶ。初期状態ではアクセス不可能なモードが指定されており、
  190:         割り当てが行われた状で指定れたモードでアクセス可能となり、解放された
  191:         時点でアクセス不可能なモードに戻る。
  192: 
  193:       ・動的割り当て領域以外のメモリは静的にモードが指定される領域であり、静的
  194:         割り当て領域と呼ばれる。動的メモリ領域と異なり、T2EXの初期化時に固定した
  195:         モードが割り当てられる。T2EXの初期化処理を適切に変更することで、アプリケー
  196:         ションに応じて適切なモードを割り当てる事が可能である。
  197: 
  198: 3.4 静的割り当て領域
  199: 
  200:         この節では、本実装における静的割り当て領域の実装の概要と、アプリケーション
  201:         に応じた変更方法について示す。
  202: 
  203: 3.4.1 初期化処理
  204: 
  205:         静的割り当て領域の割り当てを行うために、本実装ではELFオブジェクトにおける
  206:         セクション(以下、リンカセクション)を利用する。すなわち、同一のモードを持つ
  207:         シンボルの属するメモリ領域に対してリンカセクションを対応付けることで、リン
  208:         カセクションを通したメモリ領域の指定を行なっている。
  209: 
  210:         静的割り当て領域の設定に関係するファイルは以下の通りである。
  211: 
  212:         - kernel/sysmain/build_t2ex/tef_em1d/kernel_t2ex-rom.lnk
  213:         - kernel/sysmain/build_t2ex/tef_em1d/kernel_t2ex-ram.lnk
  214:                 シンボルの所属するリンカセクションを指定する。
  215:                 すなわち、シンボルの属するメモリ領域のモードを指定する。
  216: 
  217:         - kernel/extension/memory/t2ex/sysdepend/em1d/space.c
  218:                 各静的域に対るモードの設定を行う。(InitLogicalSpace関数)
  219: 
  220:         - kernel/sysdepend_t2ex/device/tef_em1d/icrt0_t2ex.S または icrt0_t2ex_ram.S
  221:                 静的領域を含むメモリ領域の内に対する初期化を行  222: 
  223:         具体的な例を示すと、kernel_t2ex-rom.lnk では、ユーザレベル用のデータ領域に
  224:         対するリンカセクションである .data_usr および .bss_usr を以下のように定義
  225:         している。
  226:         このルールでは、*.uo のファル名を持っオブジェクトファイル内のデータ
  227:         領域が、.data_usr, .bss_usr の各セクションに含まれるように定義される。
  228:         これらの2つのセクションは連続して割り当てられれ、その先頭・終端には
  229:         __data_usr_start, _end_usr のシンボルがそれぞれ定義される。
  230: 
  231:                 __data_usr_org = LOADADDR(.bss) + SIZEOF(.bss);
  232:                 .data_usr ALIGN(0x1000) : AT(__data_usr_org) {
  233:                         __data_usr_start = . ;
  234:                         *.uo(.data)
  235:                         *.uo(.data.*)
  236:                         *.uo(.data1)
  237:                         KEEP (*.uo(.eh_frame))
  238:                         *.uo(.gcc_except_table)
  239:                         *.uo(.sdata)
  240:                         *.uo(.sdata.*)
  241:                         . = ALIGN(4);
  242:                         _edata_usr = .;
  243:                         PROVIDE (edata_usr = .);
  244:                 }
  245:                 .bss_usr ALIGN(4) : {
  246:                         __bss_usr_start = .;
  247:                         PROVIDE (__sbss_usr_start = .);
  248:                         PROVIDE (___sbss_usr_start = .);
  249:                         *.uo(.sbss)
  250:                         *.uo(.sbss.*)
  251:                         *.uo(.scommon)
  252:                         PROVIDE (__sbss_usr_end = .);
  253:                         PROVIDE (___sbss_usr_end = .);
  254:                         *.uo(.bss)
  255:                         *.uo(.bss.*)
  256:                         *.uo(COMMON)
  257:                         . = ALIGN(4);
  258:                         _end_usr = .;
  259:                         PROVIDE (end_usr = .);
  260:                 }
  261: 
  262:         space.c 内の InitLogicalSpace 関数では、この情報を用いて初期化が行われる。
  263:         具体的には、以下の部分によって __data_usr_start から _end までの領域が、
  264:         モード PTE_USR_RW (ユーザアクセス可能・読み書き可能)に初期化される。
  265:         (なお、この場所が実行される際に la = __data_usr_start となっている。)
  266: 
  267:                 for ( ; (UW)la < (UW)&_end_usr; la = NextPage(la) ) {
  268:                         /* User data area (__data_usr_start ... _end_usr) */
  269:                         pte.w = PTE_USR_RW;
  270:                         pte.a.pfa = LADRtoPFA(la);
  271:                         SetPTE(la, pte, FALSE);
  272:                 }
  273: 
  274:         icrt0_t2ex.S は、T-Kernel 2.0 標準実装の icrt0.S に相当するが、BSS領域が
  275:         .bss, .bss_usr の2つに分割されることから、それぞれに対する初期化を分けて
  276:         行なうように変更されている。メモリ領域の変更によりもともととは異なる初期
  277:         化が必要となる場合には、このファイルを修正する必要がある。
  278: 
  279: 3.4.2 リファレンス実装における静的設定
  280: 
  281:         3.4.1 節に示す実装方法により、リファレンス実装では以下のような静的割り当て領域に
  282:         対する設定が行われている。ここで、[] 内に示した名前はそれぞれのシンボルが割り当て
  283:         られるリンカセクション名である。
  284: 
  285:         ---------------------------------------------------------------------------------
  286:                      領域                            特権レベル      ユーザレベル
  287:         =================================================================================
  288:           ユーザレベルのプログラム領域 [.text]          R,EX         R,EX
  289:           読込み専用データ領域 [.rodata]                R,EX         R,EX
  290:           特権レベルの読み書き可能データ領域            R,W          -
  291:                [.data, .bss]
  292:           ユーザレベルの読み書き可能データ領域          R,W           R,W
  293:                [.data_usr, .bss_usr]
  294:         ---------------------------------------------------------------------------------
  295: 
  296:         リファレンス実装におけるモード設定は、ユーザレベルからのシステムレベル領域に対する
  297:         書き込み権限の禁止を徹底しているほかは、全体的に簡易的かつ保守的な設定としている。
  298:         具体的には、プログラム領域・読込み専用可能データ領域については保護レベルの区別を
  299:         行なっていないため、たとえば以下の操作については許容され保護違反とはならない。
  300: 
  301:           - ユーザレベルからの静的システムプログラムコードへのアクセス
  302: 
  303:         このような設定としている理由は、システム側とユーザプログラム側で共通に利用される
  304:         コードおよび読込み専用データの共有にある。この設定では、たとえばSVCインタフェース
  305:         ライブラリ(libsvc.a)のコードを共有することができるため、プログラムコードの
  306:         置かれるROMまたはRAMを節約することが可能となる。
  307: 
  308: 3.4.3 データ領域の割り当て
  309: 
  310:         T2EXリファレンス実装の Makefile では、従来 SRC としていたものを SRC_SYS と
  311:         SRC_USR の2つに分割し、前者をシステム領域用、後者をユーザ領域用としている。
  312: 
  313:         すなわち、SRC_SYS, SRC_USR のどちらにソースファイルを指定するかによって、
  314:         カーネルにリンクされるオブジェクトの読み書き可能なデータ領域(.data, .bss)が
  315:         割り当てられる空間が以下のように異なっている。
  316: 
  317:           - SRC_SYS: 特権レベルの読み書き可能データ領域(.data, .bss)に割り当てる
  318:           - SRC_USR: ユーザレベルの読み書き可能データ領域(.data_usr, .bss_usr)に
  319:                      割り当てる
  320: 
  321:         SRC_SYS, SRC_USR の指定は以下のいずれかのファイルを通して行うことが出来る。
  322: 
  323:               kernel/sysmain/build_t2ex/tef_em1d/Makefile
  324:               kernel/sysmain/build_t2ex/Makefile.common
  325: 
  326: 3.5 保護違反例外
  327: 
  328:         割り当てが行われていない動的領域へのアクセスや、モード指定に反するメモリアクセス
  329:         違反を行った場合にはメモリ保護違反となり、保護違反例外処理が行われる。
  330: 
  331:         T2EX_MM_USE_DEFAULT_FAULT_HANDLER を 1 とした場合、保護違反処理例外ハンドラは
  332:         以下のT2EX内部のファイルで定義されており、以下のファイルに含まれる TaskMemFaultHdr()
  333:         および RawMemFaultHdr() を適切に変更することで、必要な例外処理を行うことができる。
  334: 
  335:               kernel/extension/memory/t2ex/sysdepend/em1d/exchdr.c
  336: 
  337:         本実装においては、各ハンドラはサンプルとして以下のように実装されている。
  338: 
  339:         - RawMemFaultHdr()
  340:                 デバッグ支援目的の実装であり、"*** OS SYSTEM DOWN ***" のメッセージを
  341:                 出力し、T-Monitorに遷移する。
  342: 
  343:         - TaskMemFaultHdr()
  344:                 例外を発生させたタスクに対して、例外コード 0 のタスク例外を送信する。
  345:                 タスク側はタスク例外ハンドラを定義し、例外処理を行うことで、タスク単位での
  346:                 保護違反例外処理を行うことが出来る。
  347:                 なお、タスク例外の送信が失敗した場合(対象のタスクがタスク例外ハンドラを
  348:                 実装していない場合を含む)には、RawMemFaultHdr() と同様に
  349:                 "*** OS SYSTEM DOWN ***" のメッセージを出力し、T-Monitorに遷移する。
  350: 
  351:         なお、T2EX_MM_USE_DEFAULT_FAULT_HANDLER を 0 とした場合には、上記のサンプル
  352:         実装はリンクされず、ユーザアプリケーション側でこれらの関数を定義する必要がある。
  353: 
  354: 3.6 実装上の制限事項
  355: 
  356:       以下の制限事項がある。
  357: 
  358:         - セクション単位(1MB)で管理された静的領域に対して、モードの変更を行うことは
  359:           できない。
  360: 
  361: 3.7 T2EXメモリ保護機能を利用しない設定
  362: 
  363:       T2EXのメモリ保護機能を利用しない設定とする場合、以下の設定を行う必要がある。
  364: 
  365:          - kernel/sysmain/build_t2ex/tef_em1d/Makefile
  366:               T2EX_MM を空に設定する(詳細は3.1節を参照)
  367: 
  368:          - kernel/sysdepend_t2ex/cpu/em1d/cpu_conf.h
  369:               USE_MMU を 0 に設定する。(標準では1に設定されている)
  370: 
  371:       上記の設定を行った場合の動作については、T-Kernel 2.0の実装仕様書を参照すること。
  372: 
  373: 
  374: ------------------------------------------------------------------------------
  375: 4. ファイル管理機能
  376: ------------------------------------------------------------------------------
  377: 
  378: 4.1 特殊ファイルシステム
  379: 
  380:       ファイル管理機能では、「基本FATファイルシステム」以外に,以下の2つの特殊
  381:       なファイルシステムを内部的に使用する。
  382: 
  383:   (1) ルートファイルシステム
  384: 
  385:       ファイルシステムを接続するルートディレクトリ "/" に対応した仮想的なファイ
  386:       ルシステム。
  387: 
  388:             ファイルシステム実装部名      "rootfs"
  389:             接続名                        "/"        (特別な名称)
  390:             サブディレクトリ              <接続したファイルシステムの接続名>
  391: 
  392:       ルートファイルシステムの切断や、実装部の登録の削除はできない。
  393: 
  394:   (2) コンソールファイルシステム
  395: 
  396:       標準入出力をファイルとして取り扱うための、コンソールデバイスに対応した仮
  397:       想的なファイルシステム。
  398: 
  399:             ファイルシステム実装部名      "consolefs"
  400:             接続名                        "console"
  401:             ファイル                      "stdin", "stdout", "stderr"
  402: 
  403:       コンソールファイルシステムの切断や、実装部の登録の削除はできない。ファイ
  404:       ルは上記の3つに固定され、削除や追加はできない。
  405: 
  406:       コンソールファイルシステムでは、コンソールの操作のために、コンソールドラ
  407:       イバの以下のAPIを使用する。
  408: 
  409:             ConsoleIO()       初期化
  410:             console_conf()    コンフィグレーション
  411:             console_in()      入力
  412:             console_out()     出力
  413: 
  414: 
  415: 4.2 ファイル管理共通部
  416: 
  417:   4.2.1 システム構成情報
  418: 
  419:     FsMaxFile     同時にオープン可能なファイル数(システム全体)
  420: 
  421:       システム全体としてアプリケーションタスクから同時にオープンできるファイル
  422:       の数を指定する。自動的にオープンされる標準入出力の stdin, stdout, stderr
  423:       の3つのファイルは、この数に含まれない。
  424:       最低 2 以上を設定すること。
  425: 
  426:     FsMaxFIMP     同時に登録可能なファイルシステム実装部数
  427: 
  428:       システム全体として同時に登録可能なファイルシステム実装部の数を指定する。
  429:       自動的に登録されるルートファイルシステム実装部と、コンソールファイルシステ
  430:       ム実装部は、この数に含まれないが、基本FATファイルシステム実装部は、この数
  431:       に含まれる。
  432:       最低 1 以上を設定すること。
  433: 
  434:     FsMaxCON    同時に接続可能なファイルシステムの接続数
  435: 
  436:       システム全体として同時に接続可能なファイルシステムの接続数を指定する。
  437:       自動的に接続されるルートファイルシステムと、コンソールファイルシステムは、
  438:       この数に含まれない。
  439:       最低 1 以上を設定すること。
  440: 
  441:     ※ 上記の設定値は、動的なメモリの消費量に直接的に影響するため、必要最低限の
  442:        数値に設定することが望まれる。
  443: 
  444:   4.2.2 カーネルオブジェクト
  445: 
  446:       以下のカーネルオブジェクトを消費する。
  447: 
  448:             ----------------------
  449:              種別         個数
  450:             ======================
  451:             サブシステム     1
  452:             イベントフラグ   1
  453:             ----------------------
  454: 
  455:   4.2.3 動的なメモリ確保
  456: 
  457:       以下のサイズのメモリを Kmalloc() / Kfree()により動的に確保/解放する。
  458: 
  459:             -----------------------------------
  460:             動的確保するメモリサイズ(バイト数)
  461:             ===================================
  462:             初期化時: (終了するまで解放されない)
  463:                    8 * ( TMaxTskId )
  464:                    4 * ( TMaxTskId )
  465:                    4 * ( FsMaxFile + 3 ) + 16
  466:                   24 * ( FsMaxFile + 3 )
  467:                   76 * ( FsMaxFIMP + 2 )
  468:                   60 * ( FsMaxCON  + 2 )
  469:                   PATH_MAX( =1024 ) * 2
  470:             -----------------------------------
  471:             一時的:
  472:                   PATH_MAX( =1024 )
  473:             -----------------------------------
  474: 
  475:   4.2.4 APIの実装方式
  476: 
  477:       ファイル管理機能の API は、基本的に拡張 SVC として実装しているが、例外と
  478:       して、以下の API はライブラリとして実装している。
  479: 
  480:   (1) 可変引数の処理のため
  481:       int   fs_open(const char *path, int oflag, ... /* mode_t mode */ );
  482:       int   fs_ioctl(int fd, int request, ... /* arg */ );
  483:       int   fs_fcntl(int fd, int cmd, ... /* arg */ );
  484: 
  485:   (2) 同等の API への置き換え
  486:       int   fs_creat(const char *pathname, mode_t mode);
  487:             --> fs_open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
  488: 
  489:   (3) 戻り値の対応のため
  490:       off_t    fs_lseek(int fd, off_t offset, int whence);
  491:       off64_t  fs_lseek64(int fd, off64_t offset64, int whence);
  492: 
  493:   4.2.5 カレントディレクトリの英大文字/小文字
  494: 
  495:       カレントディレクトリはファイル管理機能(共通部)で管理しており、fs_chdir()
  496:       で設定したパス名の文字列を、そのまま fs_getcwd() で戻す。
  497:       そのためFATファイルシステムのような英大文字と小文字の区別がないファイルシ
  498:       ステムでは、パス名中の英大文字と小文字が実際のファイル名と一致しない場合
  499:       がある。
  500: 
  501:       (例)  ディレクトリ /FAT/local/bin/ に対して、
  502:             fs_chdir("/FAT/Local/BIN") を実行後の fs_getcwd() では、
  503:             "/FAT/Local/BIN" が戻り、
  504:             fs_chdir("/FAT/LOCAL/bin") を実行した後の fs_getcwd() では、
  505:             "/FAT/LOCAL/bin" が戻る。
  506: 
  507:       fs_fchdir() で設定した場合は、ファイルシステム実装部の動作に依存する。
  508: 
  509: 
  510: 4.3 基本 FAT ファイルシステム実装部
  511: 
  512:   4.3.1 システム構成情報
  513: 
  514:     FsAccessTime        最終アクセス時刻の更新の可否
  515: 
  516:       最終アクセス時刻を更新するかどうかを指定する。0 を指定した場合には、最終
  517:       アクセス時刻を更新しない。0 以外を指定した場合は、最終アクセス時刻を更新
  518:       するため、ファイルの生成や書き込みを一切行わない場合でも、ファイルシステ
  519:       ムへの書き込みが発生する場合がある。( FAT ファイルシステムでの、アクセス
  520:       時刻は日単位のため、日が変わらないかぎり書き込みは発生しない )
  521: 
  522:     FiFAT_TskPri        タスク優先度
  523: 
  524:       ファイルシステムに対する実際の処理を行うタスクの優先度を指定する。
  525:       他のタスクとの依存関係は特にないが、通常はアプリケーションタスクより高い
  526:       優先度に設定すること。
  527: 
  528:     FiFAT_StkSz         タスクスタックサイズ
  529: 
  530:       ファイルシステムに対する実際の処理を行うタスクのスタックサイズ。
  531:       標準の 2048 から特に変更する必要はない。
  532: 
  533:     FiFAT_FCacheSz      FATキャッシュサイズ(バイト数)
  534:     FiFAT_FCacheNs      FATキャッシュ単位セクタ数
  535: 
  536:       FAT領域をアクセスするためのキャッシュサイズを指定する。
  537:       単位セクタ数は、ディスク入出力の単位となるページのセクタ数を指定する値で
  538:       1、または 2 の倍数を指定すること。
  539: 
  540:       ページサイズ = 単位セクタ数 * ディスクセクタサイズ(通常は512バイト)
  541:       実際のキャッシュサイズ = (キャッシュサイズ / ページサイズ) * ページサイズ
  542: 
  543:     FiFAT_RCacheSz      ルートディレクトリキャッシュサイズ(バイト数)
  544:     FiFAT_RCacheNs      ルートディレクトリキャッシュ単位セクタ数
  545: 
  546:       FAT12/16 のルートディレクトリ領域をアクセスするためのキャッシュサイズを指
  547:       定する。FAT32 では使用しない。
  548:       単位セクタ数は、ディスク入出力の単位となるページのセクタ数を指定する値で
  549:       1、または 2 の倍数を指定すること。
  550: 
  551:       ページサイズ = 単位セクタ数 * ディスクセクタサイズ(通常は512バイト)
  552:       実際のキャッシュサイズ = (キャッシュサイズ / ページサイズ) * ページサイズ
  553: 
  554:     FiFAT_DCacheSz      データキャッシュサイズ(バイト数)
  555:     FiFAT_DCacheNs      データキャッシュ単位セクタ数
  556: 
  557:       ファイル/ディレクトリのデータ領域(クラスタ領域)をアクセスするためのキャッ
  558:       シュサイズを指定する。
  559:       単位セクタ数は、ディスク入出力の単位となるページのセクタ数を指定する値で
  560:       0、1、または 2 の倍数を指定すること。0 を指定した場合は、クラスタサイズと
  561:       同じとなる。
  562: 
  563:       ページサイズ = 単位セクタ数 * ディスクセクタサイズ(通常は512バイト)
  564:                       または、クラスタサイズ(単位セクタ数 = 0 のとき)
  565:       実際のキャッシュサイズ = (キャッシュサイズ / ページサイズ) * ページサイズ
  566: 
  567:   4.3.2 カーネルオブジェクト
  568: 
  569:       接続するファイルシステムごとに、以下のカーネルオブジェクトを消費する。
  570: 
  571:             ----------------------
  572:              種別         個数
  573:             ======================
  574:             タスク           1
  575:             ランデブ         1
  576:             ----------------------
  577: 
  578:       接続された 1つのファイルシステムに対する実際の処理は、1つのタスクで順番に
  579:       処理され、そのタスクへの処理要求の送信、および処理結果の受信にランデブを
  580:       使用する。ランデブのメッセージサイズは 4 バイトである。
  581: 
  582:   4.3.3 動的なメモリ確保
  583: 
  584:       以下のサイズのメモリを Kmalloc() / Kfree()により動的に確保/解放する。
  585: 
  586:             ---------------------------------------------------------------
  587:             動的確保するメモリサイズ(バイト数)
  588:             ===============================================================
  589:             ファイルシステム接続時: (切断まで解放されない)
  590:                   2,596
  591:                   44 *  ( FiFAT_FCacheSz / ( FiFAT_FCacheNs * 512 ) )
  592:                   44 *  ( FiFAT_RCacheSz / ( FiFAT_RCacheNs * 512 ) )  (*1)
  593:                   44 *  ( FiFAT_FCacheSz / ( FiFAT_FCacheNs * 512 ) )
  594:                   (512 + 44) * 2
  595:                   4 * ( FsMaxFile )
  596:             ---------------------------------------------------------------
  597:             ファイルオープン時: (クローズするまで解放されない)
  598:                   60 + 24
  599:                   80 * N           (*2)
  600:                   PATH_MAX(=1024)   (*3)
  601:             ---------------------------------------------------------------
  602: 
  603:       (*1)  FAT12/16の場合のみ、FAT32では使用しない。
  604:       (*2)  N はファイルを構成する連続クラスタの数 / 10。
  605:             構成するクラスタがすべて不連続に配置された場合、連続クラスタの数は
  606:             ファイルサイズ/クラスタサイズとなる。
  607:       (*3)  ディレクトリオープンのときのみ。
  608: 
  609:   4.3.4 注意事項/制限事項
  610: 
  611:   (1) FAT12, FAT16, FAT32 のファイルシステムに対応する。
  612: 
  613:   (2) ショートファイル名(SFN)、および、ロングファイル名(LFN)に対応する。
  614: 
  615:       ショートファイル名の文字コードは、MS漢字コード(CP932) である。
  616: 
  617:       ファイル名として、ASCII 文字のみ使用する場合は、"FAT_ASCII_FN_ONLY" を定
  618:       義してビルドすることにより、コード変換テーブルが不要になり、コードサイズ
  619:       を大幅に小さくすることができる。
  620: 
  621:   (3) ディレクトリの再配置には対応しない。
  622: 
  623:       ロングファイル名(LFN)のためには、連続した複数のディレクトリエントリが必要
  624:       になる。ファイル生成時に連続した複数のディレクトリエントリの空きが無かっ
  625:       た場合は、ディレクトリエントリを再配置して連続した空きを作るのではなく新
  626:       たなクラスタを追加してディレクトリを拡大することで対応する。
  627: 
  628:       しかしながら、FAT12, FAT16 のルートディレクトリは拡大できないため、ディレ
  629:       クトリエントリの空きがあるにも関わらず、ファイルの生成エラーとなる場合が
  630:       ある。
  631: 
  632:   (4) ファイル通し番号は一意的な保証はない。
  633: 
  634:       FATファイルシステムにはファイル通し番号は存在しないため、ファイル通し番号
  635:       として、そのファイルに対応したディレクトリエントリのディスク先頭からの位
  636:       置をファイル通し番号としている。
  637: 
  638:       そのため、ファイル通し番号は 32ビットでは収まらず、64ビットとなるが、ファ
  639:       イル管理機能の API は、32ビットであるため、64ビットの下位 32ビットをファ
  640:       イル通し番号として戻している。そのため、異なるファイルが同じファイル通し
  641:       番号となる可能性がある。ただし、同一のディレクトリ内のファイルは全て異な
  642:       るファイル通し番号となることは保証される。
  643: 
  644:   (5) カレントディレクトリのパス名
  645: 
  646:       fs_fchdir() で戻すカレントディレクトリのパス名の英大文字と小文字はファイ
  647:       ル名の大文字と小文字を正確に反映するが、そのためにパスを辿る処理が必要に
  648:       なる。
  649: 
  650:       英大文字と小文字の区別が不要な場合は、"FAT_CURDIR_CASE_NOCARE" を定義して
  651:       ビルドすることにより、fs_fchdir()の処理を高速化し、コードサイズも少し減ら
  652:       すことができる。
  653: 
  654: 
  655: ------------------------------------------------------------------------------
  656: 5. ネットワーク通信機能
  657: ------------------------------------------------------------------------------
  658: 
  659: 5.1 LANドライバ
  660: 
  661:       T2EXリファレンス実装のネットワーク通信機能は、T-Engineリファレンスボード
  662:       (tef_em1d)のネットワーク・インタフェース・カード(NIC: Network Interface
  663:       Card)用の T-Engine 標準デバイスドライバ仕様 LAN ドライバを用いる。この
  664:       LAN ドライバは、T2EX リファレンス実装のソースコードと一緒に提供され、実機
  665:       (tef_em1d) と tef_em1d 用エミュレータ(QEMU-tef_em1d)に共通で利用可能なデ
  666:       バイスドライバである。
  667: 
  668:       ネットワーク通信機能におけるハードウェア依存部は LAN ドライバのみである。
  669:       T2EXリファレンス実装のネットワーク通信機能を tef_em1d とは異なるハードウェ
  670:       アへ移植する場合、LAN ドライバを移植すればよい。
  671: 
  672: 5.2 同時にオープン可能なソケットの最大数
  673: 
  674:       同時にオープン可能なソケットの最大数はシステム構成情報の SoMaxSocket で設
  675:       定できる。この数は、so_socket() で生成されるソケットと so_accept() により
  676:       生成されるソケットの合計数である。
  677: 
  678:       1 つのソケットの生成に必要なカーネルオブジェクトは、「5.7 カーネルオブジェ
  679:       クト」を参照すること。
  680: 
  681: 5.3 接続可能なデバイスドライバの最大数
  682: 
  683:       so_ifattach() でネットワーク通信マネージャに接続可能なデバイスドライバの
  684:       数には制限がある。接続可能なデバイスドライバの最大数は以下のヘッダーファ
  685:       イルの TKN_NIFDEV_MAX で定義されている。
  686: 
  687:         ${BD}/t2ex/network/net/src/netmain/tkn_init.h
  688: 
  689:         #define TKN_NIFDEV_MAX   3
  690: 
  691: 5.4 LANドライバに登録されるバッファ
  692: 
  693:   (1) 登録されるバッファ数
  694: 
  695:       so_ifattach() でデバイスドライバを接続すると、受信に必要なバッファをその
  696:       デバイスドライバに登録する。デバイスドライバに登録される受信バッファの個
  697:       数はシステム構成情報の SoDrvRxBufNum で設定する。
  698: 
  699:   (2) バッファサイズ
  700: 
  701:       デバイスドライバに登録されるバッファサイズは、イーサネットの最大フレーム
  702:       サイズである 1520 バイトである。この値は以下のヘッダーファイルの
  703:       TKN_RXBUF_SIZE で定義されている。
  704: 
  705:         ${BD}/t2ex/network/net/src/netmain/if_tkn.h
  706: 
  707:         #define TKN_RXBUF_SIZE   1520
  708: 
  709: 5.5 ソケットの送受信キューのバッファサイズ
  710: 
  711:       ソケットの送受信キューのバッファサイズに関連するシステム構成情報のデフォ
  712:       ルト値は以下の通りである。
  713:       
  714:       --------------------------------------
  715:         システム構成情報  サイズ(バイト数)
  716:       ======================================
  717:         SoTcpTxBufSz          32,768
  718:         SoTcpRxBufSz          32,768
  719:         SoUdpTxBufSz           9,216
  720:         SoUdpRxBufSz          41,600 
  721:         SoRawIPTxBufSz         8,192 
  722:         SoRawIPRxBufSz         8,192 
  723:         SoRawTxBufSz           8,192
  724:         SoRawRxBufSz           8,192
  725:       --------------------------------------
  726: 
  727:       TCP のフロー制御の最大ウィンドウサイズは、送信キューまたは受信キューのバッ
  728:       ファサイズに依存する。システム構成情報の SoTcpDoAutoTx, SoTcpDoAutoRx に
  729:       1 を設定すると、送信キューまたは受信キューのバッファサイズは通信相手のウィ
  730:       ンドウサイズに合わせて動的に変更される(自動リサイズ)。これらのシステム構
  731:       成情報のデフォルト値は 0 である。
  732: 
  733:       自動リサイズに関連するシステム構成情報のデフォルト値は以下の通りである。
  734: 
  735:       --------------------------------------
  736:         システム構成情報  サイズ(バイト数)
  737:       ======================================
  738:         SoTcpIncAutoTx        16,384
  739:         SoTcpMaxAutoTx       262,144
  740:         SoTcpIncAutoRx        16,384
  741:         SoTcpMaxAutoRx       262,144
  742:       --------------------------------------
  743: 
  744: 5.6 動的なメモリ確保への変更
  745: 
  746:       移植元となったソースコードにおいてスタック上に数KBのバッファを確保してい
  747:       たものがあった。元の実装では組込み機器用として適当ではないので、malloc()
  748:       等で動的に確保するように改良した。
  749: 
  750:       ---------------------------------------------------------------
  751:         関数名               ファイルパス
  752:       ===============================================================
  753:         res_queryN()         net/src_bsdlib/libc/net/getaddrinfo.c
  754:         getanswer()          net/src_bsdlib/libc/net/getaddrinfo.c
  755:         _gethtent()          net/src_bsdlib/libc/net/getaddrinfo.c
  756:         res_querydomainN()   net/src_bsdlib/libc/net/getaddrinfo.c
  757:         getanswer()          net/src_bsdlib/libc/net/gethnamaddr.c
  758:         res_nquery()         net/src_bsdlib/libc/resolv/res_query.c
  759:         res_nquerydomain()   net/src_bsdlib/libc/resolv/res_query.c
  760:         res_nameinquery()    net/src_bsdlib/libc/resolv/res_send.c
  761:         res_queriesmatch()   net/src_bsdlib/libc/resolv/res_send.c
  762:       ---------------------------------------------------------------
  763:           (*) ファイルパスは「${BD}/t2ex/network/」を省略している。
  764: 
  765:       動的に確保されるバッファのサイズは次のヘッダーファイルで定義されている。
  766: 
  767:         ${BD}/t2ex/network/net/src_bsdlib/libc/include/port_before.h
  768: 
  769:         #define T2EX_NS_MAXPACKET   (64*1024)
  770:         #define T2EX_NS_HOSTBUFSZ   (8*1024)
  771:         #define T2EX_NS_MAXDNAME    (1025)
  772:         #define T2EX_NS_THRESHOLD   (1024)
  773: 
  774:       T2EX_NS_MAXPACKET
  775:         DNS パケットの送受信用バッファのサイズ
  776:         - res_queryN() [getaddrinfo.c]
  777: 
  778:       T2EX_NS_HOSTBUFSZ
  779:         DNS パケットの解析用バッファのサイズ
  780:         - getanswer() [getaddrinfo.c]
  781:         - _gethtent() [getaddrinfo.c]
  782: 
  783:       T2EX_NS_MAXDNAME
  784:         DNS ホスト名の展開または圧縮に用いられるバッファのサイズ
  785:         - getanswer() [getaddrinfo.c]
  786:         - res_querydomainN() [getaddrinfo.c]
  787:         - getanswer() [gethnamaddr.c]
  788:         - res_nquerydomain() [res_query.c]
  789:         - res_nameinquery() [res_send.c]
  790:         - res_queriesmatch() [res_send.c]
  791: 
  792:       T2EX_NS_THRESHOLD
  793:         DNS のクエリパケット用バッファのサイズ
  794:         - res_nquery() [res_query.c]
  795: 
  796: 5.7 カーネルオブジェクト
  797: 
  798:   (1) ネットワーク通信機能初期化時に消費されるカーネルオブジェクト
  799: 
  800:       so_main() によりネットワーク通信機能を初期化すると以下の数のカーネルオブ
  801:       ジェクトが消費される。
  802: 
  803:         ----------------------
  804:             種別         個数
  805:         ======================
  806:           タスク           6
  807:           セマフォ         5
  808:           イベントフラグ   5
  809:           ミューテックス   1
  810:           ランデブ         1
  811:           周期ハンドラ     1
  812:           サブシステム     1
  813:         ----------------------
  814: 
  815:   (2) デバイスドライバ接続時に消費されるカーネルオブジェクト
  816: 
  817:       so_ifattach() によりデバイスドライバを接続すると以下の数のカーネルオブジェ
  818:       クトが消費される。
  819: 
  820:         --------------------------
  821:             種別             個数
  822:         ==========================
  823:           タスク               1
  824:           メッセージバッファ   1
  825:         --------------------------
  826: 
  827:   (3) ソケットの生成により消費されるカーネルオブジェクト
  828: 
  829:       so_socket() または so_accept() によりソケットを 1 つ生成すると以下の数の
  830:       カーネルオブジェクトが消費される。
  831: 
  832:         -------------------------------------------
  833:             種別                    個数
  834:         ===========================================
  835:           イベントフラグ   ceil(2/32) + ceil(4/32)
  836:         -------------------------------------------
  837: 
  838:       表中の「2/32」「4/32」は、それぞれイベントフラグの「2 ビット分」「4 ビッ
  839:       ト分」を意味している。また、ceil() は天井関数であり、ceil(x) は実数 x に
  840:       対して最小の整数を表す。
  841: 
  842:       また、so_socket() と so_accept() により生成されるソケットの合計数が N 個
  843:       の場合、以下の個数のイベントフラグが必要になる。
  844: 
  845:         ceil((2*N)/32) + ceil((4*N)/32)
  846: 
  847:       (計算例) N=9 の場合
  848:           ceil((2*9)/32) + ceil((4*9)/32)
  849:         = ceil(18/32) + ceil(36/32)
  850:         = 1 + 2
  851:         = 3
  852: 
  853:   (4) ネットワーク通信機能で必要となるカーネルオブジェクト
  854: 
  855:       接続されるデバイスドライバの最大数を D, 生成されるソケットの最大数を S
  856:       (これはシステム構成情報の SoMaxSocket に等しい) とおくと、下表のようにま
  857:       とめられる。
  858: 
  859:         --------------------------------------------------------------------
  860:             種別               個数
  861:         ====================================================================
  862:           タスク               6 + D
  863:           セマフォ             5
  864:           イベントフラグ       1 + ceil((57 + 2*S)/32) + ceil((37 + 4*S)/32)
  865:           ミューテックス       1
  866:           メッセージバッファ   D
  867:           ランデブ             1
  868:           周期ハンドラ         1
  869:           サブシステム         1
  870:         --------------------------------------------------------------------
  871: 
  872:       イベントフラグの天井関数の中に表れる定数項(57と37)は、so_main() による初
  873:       期化時に消費されるイベントフラグのビット数である。
  874: 
  875: 5.8 実行環境の設定
  876: 
  877:       T-Engineリファレンスボード(tef_em1d)で動作を確認する場合、特に設定する項
  878:       目はない。LAN ケーブルが本体に接続されていることを確認してプログラムを実
  879:       行する。
  880: 
  881:       ここでは、T-Engine リファレンスボード (tef_em1d) 用エミュレータ
  882:       (QEMU-tef_em1d) で T2EX ネットワーク通信機能を使用するための実行環境の設
  883:       定方法を説明する。
  884: 
  885:       QEMU-tef_em1d の説明書に記述されているように、起動時のパラメータ指定によ
  886:       り QEMU-tef_em1d はホストOS上の仮想ネットワークデバイス(TAP)を使用できる。
  887: 
  888:       また、QEMU-tef_em1d とホストOS間で通信を行うためには、ネットワークを適切
  889:       に構築する必要がある。本書では、ブリッジ接続を利用して QEMU-tef_em1d とホ
  890:       ストOS間の通信、および、QEMU-tef_em1d から物理ネットワークに直接アクセス
  891:       するネットワークを構築する。
  892: 
  893:   (1) 前提条件
  894: 
  895:    (a) ホストOS
  896: 
  897:       Windows 7, Windows Vista, Windows XP
  898:       (QEMU-tef_em1d が動作するホスト OS に準ずる)
  899: 
  900:       下記の作業を行うには、Windows の管理者権限が必要である。
  901: 
  902:   (2) TAP デバイス
  903: 
  904:    (a) OpenVPN のインストール
  905: 
  906:       以下の URL から OpenVPN のインストーラをダウンロードする。
  907: 
  908:         http://openvpn.net/index.php/download/community-downloads.html
  909:         (「Windows Installer」のリンクからダウンロードする)
  910: 
  911:       ダウンロードした「openvpn-2.2.2-install.msi」を実行し、画面の指示に従い
  912:       OpenVPN をインストールする。
  913: 
  914:       インストール中に下記のメッセージが表示されたら、「インストール(I)」を選択
  915:       する。
  916: 
  917:         このデバイスソフトウェアをインストールしますか?
  918:           名前: TAP-Win32 Provider V9 ネットワークアダプター
  919:           発行元: OpenVPN Technologies, Inc.
  920: 
  921:     (b) TAP デバイスの名称変更
  922: 
  923:       OpenVPN でインストールされた TAP デバイスの名前には、日本語が含まれている
  924:       可能性がある。名前に日本語が含まれていると QEMU-tef_em1d から利用できない
  925:       ので、適切な名前に変更する必要がある。
  926: 
  927:       以下の手順で「ネットワーク接続」を表示させる。
  928: 
  929:       - Windows 7 の場合
  930:       
  931:         1) スタートメニューから「コントロールパネル」を開く。
  932:         2) 「ネットワークの状態とタスクの表示」をクリックする。
  933:         3) 「アダプターの設定の変更」をクリックする。
  934: 
  935:       - Windows Vista の場合
  936:       
  937:         1) スタートメニューから「コントロールパネル」を開く。
  938:         2) 「ネットワークとインターネット」をクリックする。
  939:         3) 「ネットワークセンター」をクリックする。
  940:         4) 「ネットワーク接続の管理」をクリックする。
  941: 
  942:       - Windows XP の場合
  943:       
  944:         1) スタートメニューから「コントロールパネル」を開く。
  945:         2) 「ネットワークとインターネット接続」をクリックする。
  946:         3) 「ネットワーク接続」をクリックする。
  947: 
  948:       「TAP-Win32 Adapter V9」という表記のあるアダプタが、OpenVPN でインストー
  949:       ルされた TAP デバイスである。このアダプタを右クリックして「名前の変更」を
  950:       選択する。
  951: 
  952:       変更する名前は何でも構わないが、スペースは使わずに ASCII 文字のみを用いる
  953:       こと。以下、ここで名称を「MY-TAP」に変更した前提で説明を続ける。
  954: 
  955:   (3) ブリッジ接続
  956: 
  957:       「ネットワーク接続」を表示させる。((2)(b)参照)
  958: 
  959:       まず、ホストPCが利用しているネットワークアダプタを確認する。そのネットワー
  960:       クアダプタと先程作成した TAP デバイスを、Ctrl キーを押しながら選択する。
  961:       選択されているいずれかのアダプタを右クリックし、「ブリッジ接続」をクリッ
  962:       クする。
  963: 
  964:   (4) QEMU-tef_em1d のパラメータ
  965: 
  966:       ${BD}/kernel/sysmain/src/network_sample/ に qemu-net.bat がある。
  967:       このファイルを QEMU-tef_em1d のインストールディレクトリ C:\qemu\bin\ に
  968:       コピーする。ネットワーク通信機能を使用するプログラムを実行する場合は、qemu.bat 
  969:       の代わりに qemu-net.bat を使用する。
  970: 
  971:       qemu-net.bat は qemu.bat に以下のオプションを追加している。環境に合わせて
  972:       適宜修正すること。
  973: 
  974:       -net nic,macaddr=52:54:00:12:34:56
  975: 
  976:         QEMU-tef_em1d の NIC の MAC アドレスを設定する。複数の QEMU-tef_em1d を
  977:         実行する場合は、それぞれ異なる MAC アドレスを設定する必要がある。なお、
  978:         移植元の QEMU の man ページには以下の MAC アドレスを使用しているサンプ
  979:         ルが記述されている。
  980: 
  981:           52:54:00:12:34:56, 52:54:00:12:34:57, 52:54:00:12:34:58
  982: 
  983:       -net tap,ifname=MY-TAP
  984: 
  985:         TAP デバイスの名前を設定する。
  986: 
  987: 5.9 ネットワークの動作確認
  988: 
  989:       ここでは、サンプルプログラムを用いてネットワークの動作を確認するまでの手
  990:       順を説明する。
  991: 
  992:   (1) ソースコードの修正
  993: 
  994:       ${BD}/kernel/sysmain/src/appl_main.c の appl_main() を修正する。以下の
  995:       関数呼び出しで必要とされるヘッダーファイル net_test.h を次のようにインク
  996:       ルードする。
  997: 
  998:         #include "network_sample/net_test.h"
  999: 
 1000:       appl_main() に以下の関数呼び出しを追加する。
 1001: 
 1002:         net_test();
 1003: 
 1004:       net_test() 関数は、DHCP を用いてアドレスを設定することを想定している。静
 1005:       的にアドレスを設定する場合は、アドレス設定関連のマクロを設定し、以下のファ
 1006:       イルの net_test() 内のnet_conf() へ渡すパラメータを修正する。詳細は
 1007:       「5.11 ネットワークユーティリティ (1) ネットワークインタフェースの設定」
 1008:       を参照すること。
 1009: 
 1010:         ${BD}/kernel/sysmain/src/network_sample/net_test.c
 1011: 
 1012:   (2) ネットワークのサンプルプログラムのビルド方法
 1013: 
 1014:       サンプルプログラムのビルド用 Makefile.sample をインクルードするために、
 1015:       ${BD}/kernel/sysmain/build_t2ex/tef_em1d/Makefile の最後に次の一行を追加する。
 1016: 
 1017:         include ../../src/network_sample/Makefile.sample
 1018: 
 1019:       ビルドする場合は、通常のビルドと同様、以下のディレクトリで make を実行す
 1020:       る。
 1021: 
 1022:         ${BD}/kernel/sysmain/build_t2ex/tef_em1d
 1023: 
 1024:   (3) ネットワークのサンプルプログラムの動作確認
 1025: 
 1026:       実機上で実行する場合、通常と同様の手順でプログラムを転送して実行する。エ
 1027:       ミュレータ上で実行する場合、ビルドしたバイナリを 5.8(4) で設定した
 1028:       qemu-net.bat から実行する。
 1029: 
 1030:       ネットワークインタフェースの設定結果とサンプルプログラムの動作結果が出力
 1031:       される。
 1032: 
 1033: 5.10 ネットワーク通信機能を利用するプログラム開発
 1034: 
 1035:       ネットワーク通信機能が提供するソケットを用いて通信するためには、ネットワー
 1036:       ク通信機能を初期化してからネットワークインタフェースを適切に設定する必要
 1037:       がある。
 1038: 
 1039:   (1) ネットワーク通信機能の初期化
 1040: 
 1041:       so_main(0, NULL);
 1042: 
 1043:   (2) ネットワークインタフェースの設定
 1044: 
 1045:       サンプルプログラムの net_test() の中で呼ばれている net_conf() を呼ぶこと
 1046:       により、ネットワークインタフェース Neta に対して必要なアドレス設定を行う
 1047:       ことができる。
 1048: 
 1049:       net_conf() およびその他のネットワークユーティリティについては「5.11 ネッ
 1050:       トワークユーティリティ」を参照すること。
 1051: 
 1052:       ネットワークインタフェースの設定完了後は、ソケットを用いた通信を行える。
 1053: 
 1054: 5.11 ネットワークユーティリティ
 1055: 
 1056:       ネットワークユーティリティのサンプルプログラムを提供する。
 1057: 
 1058:       ネットワークユーティリティをビルドする場合は、
 1059:       ${BD}/kernel/sysmain/build_t2ex/tef_em1d/Makefile の最後に次の一行を追加する。
 1060: 
 1061:         include ../../src/network_sample/Makefile.sample
 1062: 
 1063:       通常のビルドと同様、以下のディレクトリで make を実行する。
 1064: 
 1065:         ${BD}/kernel/sysmain/build_t2ex/tef_em1d
 1066: 
 1067:   (1) ネットワークインタフェースの設定
 1068: 
 1069:       #include "network_sample/util.h"
 1070:       int net_conf(int emu, int dhcp);
 1071: 
 1072:       パラメータ
 1073: 
 1074:         int     emu     エミュレータかどうか
 1075:         int     dhcp    アドレスの設定方法
 1076: 
 1077:       説明
 1078: 
 1079:         ネットワークインタフェース Neta を設定する。so_main() でネットワーク通
 1080:         信機能を初期化してから呼ぶ。
 1081: 
 1082:         - ループバックデバイスの設定
 1083:         - ネットワークインタフェース Neta の設定
 1084:         - デフォルトゲートウェイの設定
 1085:         - DNS関連の設定
 1086:         - ホスト名テーブルの設定
 1087: 
 1088:         net_conf() は、T2EX API コールに加えて 5.11(3) 以降のネットワークユーティ
 1089:         リティ関数を内部的に利用している。
 1090: 
 1091:         実機で実行する場合は emu に 0 を指定する。エミュレータで実行する場合は
 1092:         emu に 1 を指定する。emu 用に以下の定数が定義されている。
 1093: 
 1094:           #define NET_CONF_MACHINE  (0)
 1095:           #define NET_CONF_EMULATOR (1)
 1096: 
 1097:         DHCP でアドレスを設定する場合は dhcp に 1 を指定する。静的にアドレスを
 1098:         設定する場合は dhcp に 0 を指定する。dhcp 用に以下の定数が定義されてい
 1099:         る。
 1100: 
 1101:           #define NET_CONF_STATIC (0)
 1102:           #define NET_CONF_DHCP   (1)
 1103: 
 1104:         なお、静的にアドレスを設定する場合、以下のファイルの先頭に定義されてい
 1105:         るマクロを直接編集する。
 1106: 
 1107:           ${BD}/kernel/sysmain/src/network_sample/net_conf.c
 1108: 
 1109:           - IPADDR:     IP アドレス
 1110:           - NETMASK:    ネットマスク
 1111:           - GATEWAY:    ゲートウェイ
 1112:           - DNSSERVER1: 1つ目のDNSサーバ (不要の場合はコメントアウトする)
 1113:           - DNSSERVER2: 2つ目のDNSサーバ (不要の場合はコメントアウトする)
 1114:           - DNSSERVER3: 3つ目のDNSサーバ (不要の場合はコメントアウトする)
 1115:           - DNSDOMAIN:  DNSの検索ドメイン (不要の場合はコメントアウトする)
 1116: 
 1117:       使用例 (実機で DHCP を使用する場合)
 1118: 
 1119:         net_conf(NET_CONF_MACHINE, NET_CONF_DHCP);
 1120: 
 1121:       使用例 (エミュレータで静的にアドレスを設定する場合)
 1122: 
 1123:         net_conf(NET_CONF_EMULATOR, NET_CONF_STATIC);
 1124: 
 1125:         (*) net_conf.c の上記マクロを適切に設定しておくこと
 1126: 
 1127:   (2) ネットワークインタフェースの情報表示
 1128: 
 1129:       #include "network_sample/util.h"
 1130:       void net_show(void);
 1131: 
 1132:       解説
 1133: 
 1134:         ネットワークインタフェースに関連する以下の情報を表示する。
 1135:   
 1136:          - ネットワークインタフェースに設定されたアドレス情報
 1137:          - DNS関連の設定
 1138:          - ホスト名テーブル
 1139:          - 経路情報
 1140: 
 1141:   (3) ネットワークインタフェースのアドレス設定
 1142: 
 1143:       #include "network_sample/util.h"
 1144:       void set_ifaddr(const char* ifname, in_addr_t addr, in_addr_t mask)
 1145: 
 1146:       パラメータ
 1147:       
 1148:         const char*     ifname          インタフェース名
 1149:         in_addr_t       addr            アドレス
 1150:         in_addr_t       mask            ネットワークマスク
 1151: 
 1152:       解説
 1153: 
 1154:         ifname で指定されたインタフェースにアドレス addr とネットワークマスク
 1155:         mask を設定する。
 1156: 
 1157:   (4) ネットワークインタフェースの起動/停止
 1158: 
 1159:       #include "network_sample/util.h"
 1160:       int if_updown(const char* ifname, int is_up)
 1161: 
 1162:       パラメータ
 1163: 
 1164:         const char*     ifname          インタフェース名
 1165:         int             is_up           インタフェースの起動/停止
 1166: 
 1167:       解説
 1168: 
 1169:         ifname で指定されたインタフェースを起動または停止する。
 1170: 
 1171:         インタフェースを起動する場合は is_up に 0 以外の値を指定する。インタ
 1172:         フェースを停止する場合は is_up に 0 を指定する。
 1173: 
 1174:   (5) 経路の追加
 1175: 
 1176:       #include "network_sample/route.h"
 1177:       void route_add(in_addr_t dest, in_addr_t gate, in_addr_t mask, 
 1178:                      int index, int direct);
 1179: 
 1180:       パラメータ
 1181: 
 1182:         in_addr_t       dest    宛先アドレス
 1183:         in_addr_t       gate    ゲートウェイアドレス
 1184:         in_addr_t       mask    ネットワークマスク
 1185:         int             index   インタフェースのインデックス
 1186:         int             direct  宛先アドレスに直接到達可能かどうかを示す値
 1187: 
 1188:       解説
 1189: 
 1190:         宛先アドレス dest、ゲートウェイアドレス gate、ネットワークマスク mask
 1191:         の経路情報をルーティングテーブルに追加する。
 1192: 
 1193:         index にはインタフェースのインデックスを指定する。この値は、
 1194:         so_ifnametoindex() などで取得することができる。
 1195: 
 1196:         宛先アドレスに直接接続されている場合は direct に 0 以外の値を設定し、そ
 1197:         れ以外の場合は direct に 0 を設定する。direct に 0 を設定すると経路情報
 1198:         のフラグに RTF_GATEWAY を設定し、direct に 0 以外の値を設定すると経路情
 1199:         報のフラグに RTF_GATEWAY を設定せずに RTF_HOST を設定する。
 1200: 
 1201:         デフォルトゲートウェイを指定する場合は dest, mask に INADDR_ANY を指定
 1202:         する。
 1203: 
 1204:   (6) 経路の削除
 1205: 
 1206:       #include "network_sample/route.h"
 1207:       void route_delete(in_addr_t dest, in_addr_t mask, int index, int direct);
 1208: 
 1209:       パラメータ
 1210: 
 1211:         in_addr_t       dest    宛先アドレス
 1212:         in_addr_t       gate    ゲートウェイアドレス
 1213:         in_addr_t       mask    ネットワークマスク
 1214: 
 1215:       解説
 1216: 
 1217:         宛先アドレス dest、ゲートウェイアドレス gate、ネットワークマスク mask
 1218:         の経路情報をルーティングテーブルから削除する。
 1219: 
 1220:         デフォルトゲートウェイを指定する場合は dest, mask に INADDR_ANY を指定
 1221:         する。
 1222: 
 1223:   (7) 経路の一覧表示
 1224: 
 1225:       #include "network_sample/route.h"
 1226:       void dump_rtlist(void);
 1227: 
 1228:       解説
 1229: 
 1230:         ルーティングテーブルのエントリを標準出力に表示する。
 1231: 
 1232:   (8) ホスト名テーブルのエントリ追加
 1233: 
 1234:       #include "network_sample/util.h"
 1235:       void add_hosttable(const char* hostname, in_addr_t addr);
 1236: 
 1237:       パラメータ
 1238: 
 1239:         const char*     hostname        ホスト名
 1240:         in_addr_t       addr            アドレス
 1241: 
 1242:       解説
 1243: 
 1244:         ホスト名 hostname にアドレス addr を割り当てるエントリをホスト名テーブ
 1245:         ルに追加する。
 1246: 
 1247:   (9) DHCP によるアドレス設定
 1248: 
 1249:       #include "network_sample/dhclient.h"
 1250:       int dhclient(const char* ifname);
 1251: 
 1252:       パラメータ
 1253: 
 1254:         const char*     ifname          インタフェース名
 1255: 
 1256:       解説
 1257: 
 1258:         ifname で指定されたインタフェースに対して、DHCP を用いて以下の設定を行
 1259:         う。
 1260: 
 1261:         - ネットワークインタフェースのアドレス設定
 1262:         - デフォルトゲートウェイの設定
 1263:         - DNS関連の設定
 1264: 
 1265: 5.12 実装上の制限事項
 1266: 
 1267:       以下の制限事項がある。
 1268: 
 1269:       - 元のソースコードではIPヘッダのIDフィールドにランダムな値を設定する機能
 1270:         があるが、本実装ではメモリ使用量を削減するためにこの機能を提供しない。
 1271: 
 1272: 
 1273: ------------------------------------------------------------------------------
 1274: 6. カレンダ機能
 1275: ------------------------------------------------------------------------------
 1276: 
 1277:       以下の制限事項がある。
 1278: 
 1279:       - time_t 型の引数または戻り値を持つAPIコールにおいて、SYSTIM, SYSTIM_U で
 1280:         表現できない範囲の時刻を指定した場合、エラーとなる。
 1281:         具体的には、1985年1月1日00:00:00以前の時刻を指定した場合、エラーとなる。
 1282: 
 1283:       - dt_strptime() において %U, %W を指定した場合、文字列中の値は無視され
 1284:         tm に格納されない。
 1285: 
 1286: 
 1287: ------------------------------------------------------------------------------
 1288: 7. プログラムロード機能
 1289: ------------------------------------------------------------------------------
 1290: 
 1291: 7.1 プログラムモジュールの作成
 1292: 
 1293:       本実装ではプログラムモジュールのフォーマットとしてELFオブジェクトをサポートする。
 1294: 
 1295:       プログラムモジュールは ${BD}/module/etc/makerules に含まれるビルドルールを
 1296:       用いることで作成できる。以下のディレクトリにシステムプログラムモジュールおよび
 1297:       一般プログラムモジュールのサンプルが含まれているので、これらを参考にすること。
 1298: 
 1299:         ${BD}/module/test-sys
 1300:            システムプログラムモジュールのサンプル
 1301:            
 1302:         ${BD}/module/test-usr
 1303:            一般プログラムモジュールのサンプル
 1304: 
 1305: 7.2 制限事項
 1306: 
 1307:       以下の制限事項がある。
 1308: 
 1309:       - 一般プログラムモジュールの初期化処理および終了処理は、pm_load() の実行時に
 1310:         ロード先の空間指定によらず常にシステムレベルで実行される。
 1311: 
 1312: 
 1313: ------------------------------------------------------------------------------
 1314: 8. 標準C互換ライブラリ
 1315: ------------------------------------------------------------------------------
 1316: 
 1317:       標準C互換ライブラリは ${BD}/lib/libtk の一部と、${BD}/lib/libc
 1318:       で実装されている。
 1319: 
 1320:       本実装において、標準C互換ライブラリのデータ領域はユーザレベル(.data_usrおよび
 1321:       .bss_usr)に配置される。
 1322: 
 1323: 
 1324: ------------------------------------------------------------------------------
 1325: ------------------------------------------------------------------------------