アドレス空間管理機能は、論理アドレス空間に対して各種の操作や管理を行うための機能である。本機能は、主としてMMUやページテーブルを操作することによって実現され、タスク固有空間の設定を行うアドレス空間設定、アクセス権のチェックを行うアドレス空間チェック、メモリ領域のロック(常駐化)、論理アドレスと物理アドレスの変換やマッピングなどの機能を提供する。
本機能は、デバイスドライバやサブシステム等のシステムプログラムを実装するために利用されるほか、デマンドページングに関する処理を行うサブシステムを併用することにより、仮想記憶システムを実現するためにも利用される。
なお、MMUを使用しないシステムであっても、アドレス空間管理機能のAPIは提供される。移植性や拡張性への配慮から、MMUを使用しないシステム上でも、アプリケーションがこれらのAPIを適切に使用することが望ましい。
μT-Kernelでは、実行時の保護レベルとして0~3の4段階(特権モード/ユーザモードなどに相当)、アクセス対象となるメモリの保護レベルとしても0~3の4段階がそれぞれ定義されており、現在実行中の保護レベルと同じか、それより低い保護レベルのメモリにのみアクセスができる。実行時のメモリアクセス権のチェックはMMUが行う。この機能は、プログラムの不正なアクセスから、OSなどのシステムを保護するために役立つ。メモリアクセス権のチェック機能を実現するために、μT-Kernelは、MMU等の設定を適切に行う。
メモリの呼出元アクセス権情報は、基本的に拡張SVCを呼び出す直前の保護レベルでアクセスできる権利を示す情報であり、タスクごとに保持される。拡張SVCを呼び出す直前の保護レベルを示す情報であるため、一般には現在の保護レベルと一致しない。例えば、保護レベル3で実行中のタスクが拡張SVCを呼び出した場合、拡張SVCの実行中の保護レベルは0となるが、タスクがアクセスできる権利としては保護レベル3である。拡張SVC(a)からさらにネストして拡張SVC(b)を呼び出した場合、ネストして呼び出した拡張SVC(b)での呼出元アクセス権情報は、拡張SVC(b)を呼び出す直前の保護レベル、すなわち拡張SVC(a)を実行中の保護レベル0である。
メモリの呼出元アクセス権情報は次のように設定される。
タスク起動直後は、そのタスクの生成時に指定された実行時の保護レベルが、呼出元アクセス権情報として設定される。
拡張SVCを呼び出すと、呼び出す直前に実行していた実行時の保護レベルが、呼出元アクセス権情報として設定される。
拡張SVCから戻ると、呼び出す直前の呼出元アクセス権情報に戻る。
SetTaskSpace() を発行すると、対象タスクがその時点で拡張SVCを呼び出す直前に実行していた実行時の保護レベルが、自タスクの呼出元アクセス権情報として設定される。ネストして拡張SVCが呼び出されている場合には、最後に呼ばれた拡張SVCを呼び出す直前の保護レベルが設定される。なお、対象となるタスクがタスク部を実行中の場合には、対象タスクの生成時に指定された実行時の保護レベルが、自タスクの呼出元アクセス権情報として設定される。
メモリの呼出元アクセス権情報は、拡張SVCから呼び出し元の保護レベルに基づく処理を行うことを想定して保持される。一例としてアドレス空間チェック機能(ChkSpaceXXX)では、現在の実行時の保護レベルの代わりに呼出元アクセス権情報を利用することで、拡張SVCの呼び出し元の権限でのメモリアクセス権の検査が実現されている。
μT-Kernelのアドレス空間の扱いに関しては、アドレス空間項μT-Kernelの概念章で説明している。アドレス空間設定の機能では、タスクのアドレス空間と呼出元アクセス権情報を設定するAPIを提供する。
以下のすべてのサービスプロファイルが有効に設定されている場合に限り、本システムコールはサポートされる。
自タスクのタスク固有空間と呼出元アクセス権情報を、tskid
で指定したタスクの情報に基づいて設定する。これにより、このAPIを実行したタスクは、tskid
のタスクと同じアドレス空間と、指定されたタスクがその時点で拡張SVCを呼び出す直前に実行していた実行時の保護レベルを示す呼出元アクセス権情報を持つことになる。ネストして拡張SVCが呼び出されている場合には、最後に呼ばれた拡張SVCを呼び出す直前の保護レベルが自タスクの呼出元アクセス権情報として設定される。なお、tskid
で指定したタスクがタスク部を実行中の場合には、指定したタスクの生成時に指定された実行時の保護レベルが、自タスクの呼出元アクセス権情報として設定される。
なお、本APIの実行後に、tskid
のタスク(対象タスク)のアドレス空間や呼出元アクセス権情報が変わった場合でも、自タスクのアドレス空間や呼出元アクセス権情報は影響を受けない。すなわち、本APIを実行する時点における対象タスクの状態が自タスクに反映されるだけで、その後の対象タスクの状態に自タスクが追従するわけではない。
拡張SVCの実行中に本APIを実行した場合、拡張SVCから戻ると、呼出元アクセス権情報については拡張SVCの呼出前の状態に戻る。一方、タスク固有空間は拡張SVCの呼出前の状態には戻らない。本APIで設定されたタスク固有空間が、拡張SVCから戻った後もそのまま有効である。
tskid
に自タスクのタスクIDを指定することはできない。ただし、TSK_SELF により自タスクを指定した場合は、現在実行中の保護レベルの呼出元アクセス権情報が設定される。このとき、タスク固有空間は切り替わらない。
なお、呼出元アクセス権情報の設定により、実行時の保護レベルが変更されるわけではないことに注意が必要である。
SetTaskSpace() は、デバイスドライバやサブシステムの処理を行うために、処理の依頼元のタスクA(デバイス管理やサブシステムの拡張SVCを呼んだタスク)とは別の処理用タスクBが動作しているような状況において、処理用タスクBのタスク固有空間および呼出元アクセス権情報を、依頼元のタスクAと同じ設定にするために使用する。
たとえば、デバイスドライバの処理用タスクBが、デバイスから入力データを読み込み、依頼元のタスクAが指定したバッファXにそのデータを格納するケースを考える。ここで、バッファXのアドレスがタスクAのタスク固有空間の中にあり、かつ処理用タスクBと依頼元タスクAのタスク固有空間が異なっていた場合には、処理用タスクBからバッファXにアクセスできず、入力データを格納することもできない。
このようなケースでは、処理用タスクBがあらかじめ SetTaskSpace() を実行し、自タスクのタスク固有空間を依頼元タスクAと同じ設定にしておくことにより、バッファXへのアクセスが可能となる。また、処理用タスクBの呼出元アクセス権情報が依頼元タスクAと同じになるので、バッファXに入力データを格納する際のアクセス権のチェックも適切に行われる。
呼出元アクセス権情報の設定を行わず、タスク固有空間の設定のみを行う場合には、tk_set_tsp を利用する。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
現在の呼出元アクセス権情報にしたがって、指定されたメモリ領域へのアクセスが許可されているか検査する。
検査のために、ChkSpaceXXX()のAPIを提供する。APIの名称の最後の文字の意味は次の通りである。
~R 読込みアクセス権があるか検査する。
~RW 読込みおよび書込みアクセス権があるか検査する。
~RE 読込みアクセス権および実行権があるか検査する。
現在の呼出元アクセス権情報にて対象となるメモリ領域へのアクセスが許可されていない場合や、対象となるメモリ領域にメモリが存在しない場合には、E_MACV のエラーを返す。対象となるメモリ領域の一部のアクセスが許可されていない場合や、一部のメモリが存在しない場合も、同様に E_MACV のエラーを返す。
なお、検査対象のメモリ領域がタスク固有空間の場合には、現在設定されているタスク固有空間がそのまま使用される。
![]() | 補足事項 |
---|---|
低い保護レベルで動作している一般のアプリケーションタスクAが、高い保護レベルで動作するデバイスドライバやサブシステムに処理を依頼するようなケースにおいて、処理のパラメータやリターンパラメータをメモリ領域Xに置いた場合には、依頼元のタスクAがメモリ領域Xに対してアクセス可能かどうかをデバイスドライバやサブシステムの側でチェックする必要がある。このチェックを行わないと、たとえば、タスクAからアクセス権のないメモリ領域を、デバイスドライバやサブシステム経由で不正にアクセスできてしまうからである。アドレス空間チェックのAPIは、このような場面でのチェックを行うために利用することを想定した機能である。 |
addr
が示すアドレスから len
バイトの領域に対して、現在の呼出元アクセス権情報により読込みアクセスが可能かどうかを検査する。アクセス可能であれば E_OK を返し、アクセス不能であれば E_MACV を返す。
パラメータlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
addr
が示すアドレスから len
バイトの領域に対して、現在の呼出元アクセス権情報により読込みアクセスと書込みアクセスの両方が可能かどうかを検査する。両方のアクセス可能であれば E_OK を返し、少なくとも一方のアクセスが不能であれば E_MACV を返す。
パラメータlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
addr
が示すアドレスから len
バイトの領域に対して、現在の呼出元アクセス権情報により読込みアクセスが可能で、かつプログラムとして実行が可能かどうかを検査する。両方とも可能であれば E_OK を返し、少なくとも一方が不能であれば E_MACV を返す。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
str
から文字列の終端('\0')に達するか max
文字目(バイト数)に達するまでのメモリ領域に対して、現在の呼出元アクセス権情報により読込みアクセスが可能かどうかを検査する。max
=0の場合は、文字列終端まで検査する。
アクセス可能であれば、その文字列の長さ(バイト数)を返す。max
文字目までに文字列の終端があった場合は'\0'の直前までの長さ、文字列の終端より先に max
文字に達した場合は max
を返す。
アクセス不能であれば、E_MACV のエラーを返す。
パラメータmax
およびリターンパラメータrlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
str
から文字列の終端('\0')に達するか max
文字目(バイト数)に達するまでのメモリ領域に対して、現在の呼出元アクセス権情報により読込みアクセスおよび書込みアクセスが可能かどうかを検査する。max
=0の場合は、文字列終端まで検査する。
読込み、書込みともアクセス可能であれば、その文字列の長さ(バイト数)を返す。max
文字目までに文字列の終端があった場合は'\0'の直前までの長さ、文字列の終端より先に max
文字に達した場合は max
を返す。
読込み、書込みの少なくとも一方がアクセス不能であれば、E_MACV のエラーを返す。
パラメータmax
およびリターンパラメータrlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
str
からTRONコード文字列の終端(TNULL=0x0000)に達するか max
文字目(TRONコード文字数)に達するまでのメモリ領域に対して、現在の呼出元アクセス権情報により読込みアクセスが可能かどうかを検査する。max
=0の場合は、文字列終端まで検査する。
アクセス可能であれば、その文字列の長さ(TRONコード文字数)を返す。max
文字目までに文字列の終端があった場合は TNULL の直前までの長さ、文字列の終端より先に max
文字に達した場合は max
を返す。
アクセス不能であれば、E_MACV のエラーを返す。
str
は、偶数アドレスでなければならない。
パラメータmax
およびリターンパラメータrlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
str
からTRONコード文字列の終端(TNULL=0x0000)に達するか max
文字目(TRONコード文字数)に達するまでのメモリ領域に対して、現在の呼出元アクセス権情報により読込みアクセスおよび書込みアクセスが可能かどうかを検査する。max
=0の場合は、文字列終端まで検査する。
読込み、書込みともアクセス可能であれば、その文字列の長さ(TRONコード文字数)を返す。max
文字目までに文字列の終端があった場合は TNULL の直前までの長さ、文字列の終端より先に max
文字に達した場合は max
を返す。
読込み、書込みの少なくとも一方がアクセス不能であれば、E_MACV のエラーを返す。
str
は、偶数アドレスでなければならない。
パラメータmax
およびリターンパラメータrlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
論理アドレス空間管理の機能では、アドレス変換(論理アドレスから物理アドレスへの変換)、メモリの常駐化、メモリアクセス権の設定に関連したAPIを提供する。
μT-Kernelでは、メモリに対するアクセス権の管理やタスク固有空間の実現、メモリの効率的な利用などを行うために、MMUを利用したアドレス変換(論理アドレスから物理アドレスへの変換)を行っている。通常のプログラムは論理アドレス空間の中で動作しており、物理アドレスを扱う必要はないが、DMA転送を行うデバイスドライバなど、ハードウェアを直接操作する一部のシステムプログラムでは物理アドレスを扱う場合がある。この時、論理アドレスと物理アドレスとの対応関係の取得や設定を行う必要があるので、そのためのAPIとして CnvPhysicalAddr()、MapMemory()、UnmapMemory() が提供される。
また、μT-Kernel上に仮想記憶システムを実現した場合には、プログラムAからアクセスされるメモリが物理的に存在しない状態(ページアウトされた状態)が発生する。ページアウトされたメモリへのアクセスがあった場合、CPUによっては、MMUがそれを検出してページフォルトのCPU例外を発生し、その例外を処理する仮想記憶システムがページアウトされていたメモリの内容をディスク(二次記憶装置)からメモリに戻す(ページイン)。このような処理を行うことによって、プログラムAから見ると、アクセス対象メモリがページアウトされているかどうかを気にすることなく、処理を進めることができる。これは、仮想記憶システムの一般的な実装方法である。
しかし、タスク独立部実行中、ディスパッチ禁止中、割込み禁止中のプログラムでは、ページフォルト発生時にも、上記のようなページインの処理を行うことができない。このため、プログラムの実行中にページフォルトが発生しないように、あらかじめアクセス対象となるすべてのメモリをページインして常駐化しておく必要がある。また、DMA転送を行う場合や、時間制約の強いプログラムを実行する場合にも、同様の処置が必要になる。このような場合に使用するAPIとして、メモリ領域をロック(常駐化)する LockSpace() や、それを解除する UnlockSpace() が提供される。
このほか、アドレス空間の各種情報を取得する GetSpaceInfo()、メモリアクセス権の設定を行う SetMemoryAccess() といったAPIが提供される。
上記のうち、DMA転送に関連した処理を行うAPIでは、DMA転送に合わせたメモリキャッシュ制御も行う、具体的には、CnvPhysicalAddr() によって論理アドレスから物理アドレスへの変換を行う際、対象となった領域は、DMA転送ができるようにメモリキャッシュがオフになる。DMA転送の終了後、UnlockSpace() を実行してメモリの常駐解除を行うと、キャッシュオン状態に戻る。
![]() | 補足事項 |
---|---|
μT-Kernel/SMでは、論理アドレス空間と物理アドレス空間の対応関係(マッピング)、メモリのアクセス権、ページ不在や常駐化などの管理を行うために、MMUやページテーブルの設定や操作を行う。しかし、μT-Kernel本体だけで仮想記憶システムを実現するわけではない。実際に仮想記憶を実現するためには、物理メモリとディスク(二次記憶装置)との間でページインやページアウトの処理を行うなど、他にもいろいろな処理が必要である。これらの処理は、μT-Kernel本体ではなく、仮想記憶を実現するためのサブシステム(T-Kernel Extensionの一部など)によって行われる。 |
論理アドレス addr
から len
バイトのメモリ領域(ロック対象領域)をロック(常駐化)する。本APIによる常駐化の後、ロック対象領域はページアウトされなくなり、常に物理アドレス空間にマッピングされるとともに、実メモリ(物理的なメモリ)も割り当てられた状態となる。
ロック対象領域の一部がページアウトされていた場合には、その領域に対してページインの処理を行ってから常駐化する。ページインの際に実メモリの確保ができなかった場合には、E_NOMEM のエラーを返す。
同じメモリ領域に対して複数回の LockSpace() を実行することができる。このとき、LockSpace() の回数はカウントされ、同じ回数の UnlockSpace() の実行によって常駐化が解除される。すなわち、LockSpace() により常駐化した状態をネストすることができる。ただし、この場合のネストの多重度(LockSpace() と UnlockSpace() の実行回数の差)には実装依存の上限値があり、その上限値を越えて LockSpace() を実行した場合には、E_LIMIT のエラーを返す。
len
に0以下の値を指定した場合には、E_PAR のエラーを返す。また、メモリ領域ではない部分(メモリの割当てを想定していない論理アドレス)がロック対象領域に含まれていた場合には、E_MACV のエラーを返す。
本APIによるロック(常駐化)の処理は、MMUの機能を使ってページ単位で行われる。このため、addr
がページの先頭アドレスでない場合や、len
がページサイズの整数倍でない場合は、addr
と len
で指定した範囲を含むページ全体がロック対象領域となる。たとえば、len
に1を指定しても、1ページ分の領域がロックされることになる。
MMUを使用しないシステムにおいては、すべてのメモリを常駐メモリとみなすことができる。そのため、LockSpace() において具体的な処理をする必要はないが、MMUを使用するシステムとの互換性を考慮し、エラーとはせずに E_OK を返す。MMUを使用しないシステムにおいて、E_PAR などエラーをチェックするかどうかは実装依存である。
LockSpace() によるメモリ常駐化の処理のうち、ページインなどの処理は、仮想記憶を実現するサブシステムを呼び出すことによって行われる。呼出のインタフェースは実装依存である。
MapMemory() によって割り当てられた論理アドレス空間を、LockSpace() のロック対象領域に含めてはいけない。この場合の動作は保証されない。
パラメータlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
論理アドレス addr
から len
バイトの領域(アンロック対象領域)をアンロック(常駐解除)する。本APIによる常駐解除の後、アンロック対象領域はページアウトの対象になる。
また、アンロック対象領域のメモリキャッシュモードがオフになっていた場合は、オンの設定に変更する。
アンロック対象領域としては、必ず LockSpace() の発行時に指定したロック対象領域と同じ領域を指定する必要がある。ロックした領域の一部のみをアンロックすることはできない。ただし、このような使い方をした場合でも、μT-Kernelではエラーを検出できない。呼出側の責任で、必ず同じ領域を指定しなければならない。
同じメモリ領域に対して複数回の LockSpace() が実行されていた場合、同じ回数の UnlockSpace() の実行によって常駐解除される。UnlockSpace() の回数が LockSpace() の回数に満たず、常駐解除されない場合でも、UnlockSpace() はエラーとはならずに E_OK を返す。一方、まだロックされていない領域をアンロック対象領域として指定した場合には、ロックカウントのエラーとして E_LIMIT を返す。
len
に0以下の値を指定した場合には、E_PAR のエラーを返す。また、メモリ領域ではない部分(メモリの割当てを想定していない論理アドレス)がアンロック対象領域に含まれていた場合には、E_MACV のエラーを返す。
本APIによるアンロック(常駐解除)の処理は、MMUの機能を使ってページ単位で行われる。このため、addr
がページの先頭アドレスでない場合や、len
がページサイズの整数倍でない場合は、addr
と len
で指定した範囲を含むページ全体がアンロック対象領域となる。たとえば、len
に1を指定しても、1ページ分の領域がアンロックされることになる。
MMUを使用しないシステムにおいては、すべてのメモリを常駐メモリとみなすことができる。そのため、UnlockSpace() においても、LockSpace() と同様に具体的な処理をする必要はないが、MMUを使用するシステムとの互換性を考慮し、エラーとはせずに E_OK を返す。MMUを使用しないシステムにおいて、E_PAR などエラーをチェックするかどうかは実装依存である。
MapMemory() によって割り当てられた論理アドレス空間を、UnlockSpace() のアンロック対象領域に含めてはいけない。この場合の動作は保証されない。
DMA転送を行う際には、バッファとなるメモリ領域を常駐化し、メモリキャッシュモード設定をオフにした上で、バッファの物理アドレスをDMAコントローラに設定する必要がある。この場合の通常の手順は次のようになる。
LockSpace() によってバッファの常駐化を行う。
CnvPhysicalAddr() によってバッファの物理アドレスを取得するとともに、バッファのメモリキャッシュモード設定をオフにする。
バッファと入出力デバイスとの間でDMA転送を行う。
UnlockSpace() によって、バッファの常駐解除を行うとともに、バッファのメモリキャッシュモード設定をオンに戻す。
ただし、UnlockSpace() では、上記のようなAPIの発行履歴とは無関係にメモリキャッシュモードをオンに設定する。UnlockSpace() の実行によりメモリキャッシュモード設定が変更される可能性について、注意が必要である。
パラメータlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
論理アドレス vaddr
のメモリ領域に対応する物理アドレスを求め、paddr
へ返す。また、vaddr
から len
バイトのメモリ領域のうち、対応する物理アドレスが連続しているサイズ(バイト数)を戻値 rlen
に返す。すなわち、論理アドレスと物理アドレスの対応関係が連続するのは、rlen
のサイズまでであり、rlen
≦len
である。論理アドレス空間の vaddr
から rlen
のサイズの連続領域が、物理アドレス空間の paddr
から rlen
のサイズの連続領域に対応するということになる。
また、物理アドレス空間の paddr
から rlen
のサイズの領域(対象領域)に対して、メモリキャッシュモードをオフに設定する。これは、CnvPhysicalAddr() の実行後にDMA転送を行うことを想定しているためである。ただし、ハードウェアの制限から、部分的なメモリのキャッシュのオフができない場合には、キャッシュのフラッシュ(ライトバックして無効化)を行うものとする。
CnvPhysicalAddr() では、対象領域の常駐化の処理は行わない。DMA転送を行う場合には、バッファとして使用する領域に対して別途 LockSpace() を発行し、バッファ領域を常駐化(ロック)しておかなければならない。
len
に0以下の値を指定した場合には、E_PAR のエラーを返す。また、vaddr
から len
バイトの領域の中に、メモリ領域ではない部分(メモリの割当てを想定していない論理アドレス)が含まれていた場合には、E_MACV のエラーを返す。
CnvPhysicalAddr() は、DMA転送の準備のために使用することを想定したAPIである。DMA転送の際の具体的な使い方については、UnlockSpace() の補足事項を参照のこと。
CnvPhysicalAddr() の対象領域に対しては、キャッシュモードをオフに設定するだけでなく、メモリアクセスの完了を保証するメモリ属性に設定することが望ましい。
パラメータlen
およびリターンパラメータrlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
物理アドレス paddr
から len
バイトの連続領域を論理アドレス空間にマップし、マップ先の先頭の論理アドレスを laddr
に返す。マップされたメモリ領域は、常駐化(ロック)された状態となる。また、マップされたメモリ領域に、attr
で指定した属性を設定する。
attr
では、次の属性を指定する。
attr := (MM_USER || MM_SYSTEM) | [MM_READ] | [MM_WRITE] | [MM_EXECUTE] | [MM_CDIS]
MM_USER | ユーザレベルアクセス可 |
MM_SYSTEM | システムレベルアクセス可 |
MM_READ | 読込みアクセス可 |
MM_WRITE | 書込みアクセス可 |
MM_EXECUTE | プログラム実行可 |
MM_CDIS | キャッシュ禁止 |
ハードウェアや実装によっては、上記の以外の属性を指定できる場合もある。
paddr
に NULL を指定した場合には、物理アドレスの連続した len
バイトの実メモリを確保して割当てを行い、その実メモリの物理アドレス空間を論理アドレス空間にマップする。
len
に0以下の値を指定した場合には、E_PAR のエラーを返す。また、マップ先の論理アドレス空間が不足していて割当てに失敗した場合には、E_LIMIT のエラーを返す。論理アドレス空間を管理するために必要なメモリが確保できなかった場合や、paddr
に NULL を指定したケースで実メモリの確保ができなかった場合には、E_NOMEM のエラーを返す。
MapMemory() は、物理アドレス空間に置かれた入出力デバイス(Video RAMなど)の領域を、デバイスドライバなどのプログラムから直接アクセス可能な論理アドレス空間にマッピングするための機能である。
マップ先の論理アドレス laddr
は、本APIの実行時に自動的に割り当てられる。マップ先の論理アドレスを指定することはできない。
μT-Kernelが管理するシステムメモリに含まれるアドレスを paddr
に指定してはならない。MapMemory() によってシステムメモリの確保を行いたい場合には、paddr
に NULL を指定し、μT-Kernelによって自動的に割り当てられたシステムメモリを使用する。
attr
で指定する属性のシンボル(ニーモニック)に対応する値は、実装によって異なっている場合がある。そのため、互換性への配慮から、attr
の指定には必ず上記のシンボルを使用すべきである。
既に MapMemory() の対象となっている物理アドレス領域に対して、重複して MapMemory() を実行してはいけない。また、MapMemory() によって割り当てたメモリは常駐メモリであるが、この常駐は解除できず、常駐解除のために UnlockSpace()を呼び出してはならない。このような使い方をしないことは、呼出側で保証する必要がある。
MapMemory() を実行した後、何らかの方法にて、laddr
として割り当てられた論理アドレスを経由せず、paddr
以降の物理アドレスに直接アクセスした場合、キャッシュ等の不整合が生じる可能性がある。このような使い方をする場合は、呼出側の責任において、データの整合性などに十分注意する必要がある。
attr
に MM_CDIS を指定した場合のメモリ属性は、キャッシュを使用しない属性であるだけでなく、メモリアクセスの完了を保証する属性であることが望ましい。
パラメータlen
の型がINTからSZに変更されている。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
MapMemory() で割り当てられた論理アドレス空間をアンマップ(解放)する。laddr
にはアンマップの対象となる領域の論理アドレスを指定するが、この値は、MapMemory() の戻値 laddr
で得た値でなければならない。
MapMemory() の実行時に paddr
=NULL を指定し、実メモリの割当ても行っていた場合には、UnmapMemory() の実行によりそのメモリも解放される。
本APIは過去のμT-Kernelの仕様では除外されていたが、サービスプロファイルの導入によりプロファイルで許容される場合に利用が可能となった。
pk_spinfo
の内容
論理アドレス addr
から len
の領域のアドレス空間情報を取得して、リターンパラメータ pk_spinfo
に返す。paddr
には addr
に対応する物理アドレスを返す。page
には addr
が属するページの先頭の物理アドレスを返す。
pagesz
にはページサイズを返す。ページサイズは、MMUで定義されるページサイズであり、SetMemoryAccess() でメモリアクセス権を設定したり、SetCacheMode() でキャッシュモードを設定したりする際の単位となるページサイズと同じ値である。
cachesz
にはキャッシュラインサイズを返す。キャッシュラインサイズは、ControlCache() でキャッシュを制御する際の単位となるキャッシュラインサイズと同じ値である。
cont
には addr
から len
バイトの領域のうち、対応する物理アドレスが連続しているサイズ(バイト数)を返す。すなわち、論理アドレスと物理アドレスの対応関係が連続するのは、cont
のサイズまでであり、cont
≦len
である。論理アドレス空間の addr
から cont
のサイズの連続領域が、物理アドレス空間の paddr
から cont
のサイズの連続領域に対応するということになる。
途中にページアウトされている領域が存在した場合は、その領域の直前までの物理アドレスが連続しているものとみなす。特に、addr
の属するページがページアウトされていた場合は、cont
=0を返す。このとき、戻値 ercd
は E_OK を返すが、pk_spinfo
に返されるリターンパラメータのうち、cont
以外の内容は不定となる。
len
に0以下の値を指定した場合には、E_PAR のエラーを返す。エラーが発生した場合に pk_spinfo
に設定される内容は不定である。
パラメータlen
およびT_SPINFOのメンバpagesz
, cachesz
, cont
の型がINTからSZに変更されている。
T-Kernel 2.0仕様に基づき新たに追加されたAPIである。
論理アドレス addr
から len
バイトのメモリ領域に対して、mode
で指定したメモリアクセス権を設定する。また、実際にメモリアクセス権を設定できた領域のサイズ(バイト数)を戻値 rlen
に返す。
mode
では、次のメモリアクセス権を指定する。
mode := ( MM_EXECUTE | MM_READ | MM_WRITE ) MM_EXECUTE プログラム実行アクセス可能 MM_READ 読み出しアクセス可能 MM_WRITE 書き込みアクセス可能 ... /* 実装独自のモードを追加してもよい */
本APIによるメモリアクセス権の設定は、MMUの機能を使ってページ単位で行われる。このため、addr
がページの先頭アドレスでない場合や、len
がページサイズの整数倍でない場合は、addr
と len
で指定した範囲を含むページ全体がメモリアクセス権設定の対象領域となる。たとえば、len
に1を指定しても、1ページ分のメモリアクセス権が設定されることになる。
ハードウェアや実装によっては、上記の以外のメモリアクセス権を指定できる場合もある。また、ハードウェアや実装によっては、上記のメモリアクセス権の一部または全部の設定ができない場合がある。設定できないメモリアクセス権を mode
で指定した場合には、E_NOSPT のエラーを返す。
通常のアプリケーションなどで使用するメモリ領域に対しては、μT-Kernelがあらかじめ適切なメモリアクセス権の設定を行っている。このため、通常のアプリケーションが SetMemoryAccess() を使う必要はない。SetMemoryAccess() を使用するのは、システムのメモリ割当てやセキュリティを動的に管理するプログラム、デバッグ用のプログラムなど、通常のアプリケーションとは異なる特別な目的を持ったプログラムである。
mode
で指定するメモリアクセス権は、MapMemory の attr
で指定する属性の一部と共通である。
パラメータlen
およびリターンパラメータrlen
の型がINTからSZに変更されている。
T-Kernel 2.0仕様に基づき新たに追加されたAPIである。