デバイス管理機能では、 アプリケーションが各種のデバイスを統一的に取り扱うためのインタフェース機能、 および各種のデバイスに対応したデバイスドライバの登録/管理機能、 デバイスドライバとのインタフェース機能を提供している。 ここでは、アプリケーションインタフェースのみについて記述する。
また、OS 核のファイル管理機能やイベント管理機能では、 内部的にデバイス管理機能を経由して実際のデバイス操作を行なうことになる。
以下にデバイス管理機能の位置付けを示す。
使用されるデバイスとしては以下のようなものがある。
これらのデバイスのうち、 ビットマップディスプレイに対するアプリケーションインタフェースは、 デバイス管理機能とは独立したディスプレイ関数群として提供される。
これらのディスプレイ関数群は通常ドライバと一体となっているためドライバインタフェースも適用されないことになり、 デバイス管理機能とは基本的に独立した存在となる。
また、キーボードとポインティングデバイスに対するアプリケーションインタフェースはイベント管理機能として提供されるが、 ドライバとのインタフェースはデバイス管理でサポートしている。
各種のディスク装置の場合は、 通常はファイルとして使用されるが、 デバイスとして直接取り扱うためのアプリケーションインタフェースも用意される。
デバイスは文字型デバイスとブロック型デバイスの 2 種類に分類される。 文字型デバイスは基本的にバイト単位でデータの入出力をシーケンシャルに行なうもので、 ブロックデバイスはデバイス毎に定められた大きさのデータブロック単位での入出力を行なうものでブロック単位でのランダムなアクセスが可能である。
各種のディスク装置はブロック型デバイスであり、 その他のほとんどのデバイスは文字型デバイスとなる。
また、デバイスは実デバイスと仮想デバイスに分類される。 実デバイスは物理的に実際に存在する通常の意味でのデバイスであり、 仮想デバイスはある種の資源を仮想的に 1 つのデバイスとして取り扱うものである。 仮想デバイスの代表的なものとしては画面上の 1 つのウィンドウを仮想的に1つのコンソールとして取り扱う仮想コンソールがあげられる。
デバイスは、 論理デバイス名と呼ばれるユニークな文字列によりシステムに登録され、 識別される。論理デバイス名は、基本的に以下に示す 3 つの要素から構成される。
種別 + ユニット を、特にユニット名と呼び、OS で識別される単位となる。 OS 側では種別とユニットの区別は認識せず、 両方を合わせた名称であるユニット名により、 デバイスを識別する。ユニット名の最後の文字は数字であってはいけない。
論理デバイス名は、「ユニット名+サブユニット番号」で表わされ、 全体として最大 8 文字 ( 16 バイト ) の文字列となる。 サブユニット番号は前に 0 の付かない 3 桁までの数字である。 サブユニットが存在しない場合、 ユニット名がそのまま論理デバイス名と成り得る。 論理デバイス名の最後の文字が数字である場合は、 その論理デバイス名はサブユニットを表わしているものと見なされる。 サブユニット全体を表わす場合、 サブユニット番号は付けず、ユニット名そのものが論理デバイス名となる。
サブユニット ( パーティション ) を表わすために最大 3 桁の数字 ( サブユニット番号 ) が使用されるが、 サブユニットの分割を無視した 1 つのユニットとして取り扱う場合は、 サブユニット番号を含めない論理デバイス名 ( ユニット名 ) を使用する。これは、主にサブユニットの分割 (即ち、ディスクのパーティショニング ) を行なうために使用される。 なお、サブユニット番号を含まない論理デバイス名 ( ユニット名 ) を特に物理デバイス名と呼ぶ。
デバイスの登録は、実際には対応するデバイスドライバの登録を意味し、 デバイスドライバはユニット単位でユニット名により定義される。 即ち、1 つのユニットに含まれるすべてのサブユニットは 1 つのデバイスドライバで処理される。 通常、デバイスドライバはデバイスの種別に対応して用意され、 1 つのデバイスドライバで複数のユニットを処理する場合が多いが、 複数のユニットを複数のデバイスドライバで処理してもよい。
なお、今後単にデバイス名と言った場合は、 論理デバイス名を意味するものとする。
ディスク等のデバイスでは、システムの安全性を保つために、 そのデバイスを使用できるユーザを制限することが望ましい。 このため、プロセスのユーザレベルによるデバイスのアクセス制御が行なわれる。
各デバイスには以下に示す 1 ワードのアクセスモードが保持されており、 これによりデバイスのアクセス権がチェックされる ( これはファイルに於ける一般アクセスレベルに相当するものである )。
即ち、読込可能なユーザレベルを持つプロセスからのみデバイスの読込用
( D_READ
) のオープンが可能で、
書込可能なユーザレベルを持つプロセスからのみデバイスの書込用
( D_WRITE
) のオープンが可能となる。
また、 アクセス可能なユーザレベルを持つプロセスからのみ、
そのデバイスをファイルシステムとして取り扱うことが可能であり、
ファイルシステムの接続 / 切断 /
管理情報読込みのファイル管理のシステムコールを実行できる。
デバイスのアクセスモードは、 デバイスの登録時に R = W = F = 15 に設定される。 登録後はユーザレベル 0 のプロセスからのみ変更可能となる。
#define D_READ 0x0001 /* 読み込み専用オープン */ #define D_WRITE 0x0002 /* 書き込み専用オープン */ #define D_UPDATE 0x0003 /* 更新用オープン */ #define D_EXCL 0x0100 /* 排他モード指定 */ #define D_WEXCL 0x0200 /* 排他書き込みモード指定 */ #define D_NOWAIT 0x8000 /* 待ちなしモード指定 */
typedef struct dev_state { UW attr; /* デバイスの属性 */ UW mode; /* アクセスモード */ W blksz; /* 物理ブロックサイズ( -1 :不明) */ W wprt; /* 書き込み可否( 0:許可 1:禁止 -1:不明) */ } DEV_STATE;
#define L_DEVNM 8 /* デバイス名の長さ */
typedef struct { UW attr; /* デバイスの属性 */ W nsub; /* サブユニット数 */ TC name[L_DEVNM]; /* ユニット名 */ } DEV_INFO;
#define DA_DEVINFO 0xFFFF0000 /* デバイス/メディア依存情報 */ #define DA_CHARDEV 0x8000 /* 文字型デバイス */ #define DA_REMOVABLE 0x4000 /* 取り外し可能 */ #define DA_DEVKIND 0xFF /* デバイス/メディア種別 */ #define DA_DEVTYPE 0xF0 /* デバイス/メディアタイプマスク */ #define DK_UNDEF 0x00 /* 未定義/不明 */ #define DK_DISK 0x10 /* ディスクタイプ */ #define DK_DISK_UNDEF 0x10 /* その他のディスク */ #define DK_DISK_RAM 0x11 /* RAM ディスク */ #define DK_DISK_ROM 0x12 /* ROM ディスク */ #define DK_DISK_FLA 0x13 /* FLASH ROM / SS ディスク */ #define DK_DISK_FD 0x14 /* フロッピーディスク */ #define DK_DISK_HD 0x15 /* ハードディスク */ #define DK_DISK_CDROM 0x16 /* CD-ROM */
#define D_SUSPEND 0x0001 /* サスペンドする */ #define D_DISSUS 0x0002 /* サスペンドを禁止する */ #define D_ENASUS 0x0003 /* サスペンドを許可する */ #define D_CHECK 0x0004 /* サスペンド禁止カウントを調べる */ #define D_FORCE 0x8000 /* 強制サスペンド指定 */
|
WERR opn_dev(TC* dev, W o_mode, W* error)
TC* dev 対象デバイス名 W o_mode オープンモード ( D_READ ‖ D_WRITE ‖ D_UPDATE ) | [ D_EXCL ‖ D_WEXCL ] | [ D_NOWAIT ] D_READ 読み込み用オープン(Rアクセス権が必要) D_WRITE 書き込み用オープン(Wアクセス権が必要) D_UPDATE 更新(読み込み/書き込み)用オープン(RWアクセス権が必要) D_EXCL 排他モード D_WEXCL 排他書き込みモード D_NOWAIT 待ち無し指定 文字型デバイスの場合、オープン時にデバイスがレディ状態になる まで待たずにリターンする。この指定でオープンした場合は、 rea_dev(), wri_dev() で入力データが得られなかったり、出力が ビジー状態の場合には、待たずにリターンする。 W* error 詳細エラー情報格納領域 *error には、デバイスドライバから戻されたエラー情報が設定される。 エラー情報の内容は、各デバイスドライバによって異なる。 error が NULL の場合、エラー情報は格納しない。
>0 正常(デバイスディスクリプタ) <0 エラーコード
ER_ACCES : デバイス(dev)のアクセス権(R,W)がない。 ER_ADR : アドレス(dev,error)のアクセスは許されていない。 ER_BUSY : デバイス(dev)は既に排他的にオープンされている為、 同時にデバイスをオープンすることができない、 またはファイルシステムとして接続されている。 ER_DEV : デバイス(dev)に対しての読込みまたは書込み操作は許されていない。 ER_ERDEV : 装置異常が発生した。 ER_IO : 入出力エラーが発生した。 ER_LIMIT : 同時オープン可能な最大デバイス数を越えた。 ER_MINTR : メッセージハンドラが起動されたため、処理が中断された。 ER_NODEV : デバイス(dev)へのアクセスができない。 ER_NOEXS : デバイス(dev)は存在していない(登録されていない)。 ER_NOMDA : デバイス(dev)のメディアが存在しない。 ER_NOSPC : システムのメモリ領域が不足した。 ER_PAR : パラメータが不正である(o_modeが不正)。 ER_RONLY : デバイス(dev)は書込不可である。
|
ERR cls_dev(W dd, W eject, W* error)
W dd デバイスディスクリプタ W eject イジェクト指定 = 0 イジェクトしない ≠ 0 イジェクトする(イジェクト不可能なデバイスの時は無視) W* error 詳細エラー情報格納領域 *error には、デバイスドライバから戻されたエラー情報が設定される。 エラー情報の内容は、各デバイスドライバによって異なる。 error が NULL の場合、エラー情報は格納しない。
= 0 正常 <0 エラーコード
ER_ADR : アドレス(error)のアクセスは許されていない。 ER_DD : デバイスディスクリプタは存在していない。 ER_IO : 入出力エラーが発生した。 ER_MINTR : メッセージハンドラが起動されたため、処理が中断された。
|
ERR rea_dev(W dd, W start, B* buf, W size, W* a_size, W* error)
W dd デバイスディスクリプタ W start 読み込み開始データ番号 ≧0 固有データ < 0 属性データ B* buf 読み込みデータの格納領域 W size 読み込みデータサイズ 固有データ 単位はデバイス依存 属性データ 単位はバイト W* a_size 読み込んだデータサイズ 固有データ 単位はデバイス依存 属性データ 単位はバイト W* error 詳細エラー情報格納領域 *error には、デバイスドライバから戻されたエラー情報が設定される。 エラー情報の内容は、各デバイスドライバによって異なる。 error が NULL の場合、エラー情報は格納しない。
= 0 正常
<0 エラーコード
ER_ADR : アドレス(buf,a_size,error)のアクセスは許されていない。 ER_BUSY : データは得られなかった(D_NOWAITオープン時) ER_DD : デバイスディスクリプタは存在していない、 または D_WRITE オープンである。 ER_DEV : デバイス(dd)に対しての読込み操作は許されていない。 ER_ERDEV : 装置異常が発生した。 ER_IO : 入出力エラーが発生した。 ER_MINTR : メッセージハンドラが起動されたため、処理が中断された。 ER_NODEV : デバイス(dd)へのアクセスができない。 ER_NOMDA : デバイス(dd)のメディアが存在しない。 ER_PAR : パラメータが不正である(size< 0,start不正)。
|
ERR wri_dev(W dd, W start, B* buf, W size, W* a_size, W* error)
W dd デバイスディスクリプタ W start 書き込み開始データ番号 ≧0 固有データ < 0 属性データ B* buf 書き込みデータ W size 書き込みデータサイズ 固有データ 単位はデバイス依存 属性データ 単位はバイト W* a_size 書き込んだデータサイズ 固有データ 単位はデバイス依存 属性データ 単位はバイト W* error 詳細エラー情報格納領域 *error には、デバイスドライバから戻されたエラー情報が設定される。 エラー情報の内容は、各デバイスドライバによって異なる。 error が NULL の場合、エラー情報は格納しない。
=0 正常 <0 エラーコード
ER_ADR : アドレス(buf,a_size,error)のアクセスは許されていない。 ER_BUSY : データは書き込めなかった(D_NOWAITオープン時)。 ER_DD : デバイスディスクリプタは存在していない、 または D_READ オープンである。 ER_DEV : デバイス(dev)に対しての書込み操作は許されていない。 ER_ERDEV : 装置異常が発生した。 ER_IO : 入出力エラーが発生した。 ER_MINTR : メッセージハンドラが起動されたため、処理が中断された。 ER_NODEV : デバイス(dd)へのアクセスができない。 ER_NOMDA : デバイス(dd)のメディアが存在しない。 ER_PAR : パラメータが不正である(size< 0,start不正)。 ER_RONLY : デバイス(dev)は書込不可である。
|
ERR chg_dmd(TC* dev, W mode)
TC* dev 対象デバイス名 W mode アクセスモード
=0 正常 <0 エラーコード
ER_ACCES : レベル 0 のユーザでない。 ER_ADR : アドレス(dev)のアクセスは許されていない。 ER_NOEXS : デバイス(dev)は存在していない(登録されていない)。 ER_PAR : パラメータが不正である(modeが不正)。
|
ERR dev_sts(TC* dev, DEV_STATE* buf)
TC* dev 対象デバイス名 DEV_STATE* buf デバイス管理情報の格納領域typedef struct dev_state { UW attr; /* デバイスの属性 */ UW mode; /* アクセスモード */ W blksz; /* 物理ブロックサイズ(−1:不明) */ W wprt; /* 書き込み可否(0:許可 1:禁止 ー1:不明) */ } DEV_STATE; attr デバイスの属性を示す。 mode デバイスのアクセスモードを示す。 blksz デバイスの物理ブロックサイズをバイト数で示したもので、 rea_dev(), wri_dev() での単位となる値である。 文字型デバイスの場合は常に "1" となる。 wprt デバイスへの書込みが禁止されているか否かを示す状態であり、書込み禁止 の時は "1" となり、書込み許可の時は "0" となる。【リターン値】
=0 正常 <0 エラーコード【解説】
指定したデバイスの管理情報を取り出す。【エラーコード】
ER_ADR : アドレス(dev,buf)のアクセスは許されていない。 ER_NOEXS : デバイス(dev)は存在していない。
|
WERR get_dev(TC* dev, W devno)
TC* dev デバイス名の格納領域 W devno デバイス番号
≧0 正常(デバイスのサブユニット数) <0 エラーコード
ER_ADR : アドレス(dev)のアクセスは許されていない。 ER_NOEXS : デバイス番号(num)は存在していない。
|
WERR lst_dev(DEV_INFO* dev, W ndev)
DEV_INFO* dev デバイス情報の格納領域(配列) NULL 格納しない typedef struct { UW attr; /* デバイスの属性 */ W nsub; /* サブユニット数 */ TC name[L_DEVNM]; /* ユニット名 */ } DEV_INFO; W ndev デバイス情報の格納領域(配列)の要素数 0 格納しない
≧0 正常(登録されているデバイス数) <0 エラーコード
ER_ADR : アドレス(dev)のアクセスは許されていない。 ER_PAR : パラメータが不正である(ndev< 0)。
|
WERR sus_dev(UW mode)
mode ::= ( D_SUSPEND ‖ D_DISSUS ‖ D_ENASUS ‖ D_CHECK ) | [D_FORCE] D_SUSPEND 0x0001 サスペンドする D_DISSUS 0x0002 サスペンドを禁止する D_ENASUS 0x0003 サスペンドを許可する D_CHECK 0x0004 サスペンド禁止カウントを調べる D_FORCE 0x8000 強制サスペンド指定
ER_BUSY : サスペンド禁止状態のためサスペンドできなかった。 ER_PAR : パラメータが不正である。 ER_LIMIT : サスペンド禁止要求カウントがシステムの制限を超えた。 ER_MINTR : メッセージハンドラが起動されたため、処理が中断された。