第10章OSの役割 pp.114-118

120
10 章 オペレーティングシステムの役割
これまで,1 つのプログラムを高速に実行する基本的な仕組みについて学ん
できた.しかし,現在のコンピュータでは,複数のプログラムが,見かけ上同
時に動いているのが一般的である.また,ハードウェアの詳細な構造を知ら
なくてもプログラムを記述でき,さらに,ハードウェアの構造が多少異なっ
ていても,同じプログラムを動かすことができる.本章では,ハードウェア
の機能を補完・隠蔽し,複数のプログラムに対して様々な機能を提供するオ
ペレーティングシステム(OS)の基本機能を学ぶ.
10.1
ハードウェアの隠蔽と複数プログラムの実行
コンピュータの高機能化は,ハードウェアの高速化とソフトウェアの高度化に
よって成し遂げられている.ある水準以上の機能をハードウェア化すると,回路
規模が急激に増大し,動作周波数の低下により性能が損なわれるため,ハード
ウェアには必要最小限の機能が搭載される.一方,このようなハードウェアを制
御するプログラムを各利用者が個々に開発するのは難しく,異なる機種間でユー
ザプログラムを共通に利用できる可搬性も損なう.さらに,任意の複数のプログ
ラムを見かけ上同時に実行する場合,全ての実行の組み合わせを意識してプログ
ラムすることは不可能に近い.もし,各々のユーザプログラムに対して,ハード
ウェアの詳細な構造を隠蔽し,互いに干渉せず,あたかもハードウェアを占有し
ているように見せる仕掛けがあれば,以上の問題を解決できる.
図 10.1(a) に示すソースプログラムについて考えてみよう.printf は,数値を
文字列に組み込んでフォーマット出力する機能を有しており,プログラマにとっ
て使いやすい関数である.しかし,例えば文字のみを表示可能なディスプレイの
場合,主記憶アドレス上に表示文字格納レジスタが配置されているに過ぎず,書
き込まれた文字コードを表示する機能しかない.printf とハードウェアの間を埋
める機能はどのように構成されるべきであろうか.
この例で解決すべき課題は2つある.1つは,
(1)機種毎に異なる文字表示
機能や表示文字格納レジスタの位置をユーザプログラムに対して隠蔽すること.
もう1つは,
(2)表示デバイスが1つしかない場合でも,各々のユーザプログラ
Proprietary & Confidential
コンピュータアーキテクチャの巻
10 章 オペレーティングシステムの役割
121
main() { printf("Hello.\n"); }
main: ...
set L0,r1
call printf
return
L0: .ascii "Hello.\n\0"
!
!
!
!
write: ...
sys_call write
return
文字列先頭アドレスを printf の第1引数にセット
printf 関数を呼び出す
main を終了
文字列定数
(b) 生成される命令列
printf: ...
<出力データを生成>
set FD,r1
call write
return
(a) C言語ソースプログラム
! 先頭アドレスと長さを write の第2・第3引数にセット
! write 先を指示するファイルディスクリプタ (FD) を第1引数にセット
! write 関数を呼び出す
! printf を終了
(c) ライブラリ中の命令列(printf)
! 第1・第2・第3引数 (FD, アドレス, 長さ) と共に write システムコールを発行
! write を終了
(d) ライブラリ中の命令列(write)
(e) OS内の命令列(システムコール)
(f) OS内の命令列(ファイル管理機能)
device 毎命令列入口: ...
<I/O 処理>
! デバイス固有の制御レジスタへ書き込んで I/O を実行
return
! デバイスドライバを終了
ファイル管理機能の write 機能: ...
! バッファ処理された依頼に順次対応する
<対応するデバイスドライバの呼び出し> ! 適切なデバイスを選択してデバイスドライバを呼び出す
次の依頼を待つ
sys_call 入口: ...
! 特権モードに移行しOS内命令列を実行
<ファイル管理機能の write 機能にてバッファ処理>
return_from_sys_call
! 特権モードから非特権モードに復帰
(g) OS内の命令列(デバイスドライバ)
図 10.1: 文字列を表示するプログラム
コンピュータアーキテクチャの巻
Proprietary & Confidential
10.1. ハードウェアの隠蔽と複数プログラムの実行
ユーザプログラム命令列
(b)
OS命令列
main:
:
call printf
特権モードへ移行
sys_call入口
(e)
ライブラリ
(c)
printf:
:
call write
122
ス
シ
ル
ー
コ
ム
テ
return_from_sys_call
帰
復
バッファ処理
ライブラリ
(d)
(f)
write:
:
sys_call write
ファイル管理機構
デバイスドライバ
非特権モードへ復帰
(g)
制御レジスタ
I/O装置
保護機能により、直接操作はできない
図 10.2: システムコール
ムに対して専用の表示デバイスであるように見せることである.
前者(1)のためには,ユーザに使わせる記号を統一したり,表示デバイスを
ファイルとして抽象化し,その識別子や番号(ファイルディスクリプタ)をユー
ザに使わせる仕組みと,物理的なデバイスを特定する情報の対応関係を管理する
階層を設ければよい.図 10.1(d) は,ユーザプログラムに対して,write という統
一的な名称の関数を提供する階層である.後述するシステムコールをユーザプロ
グラムに直接使わせないのは,システムコールは機械語命令であり,機種依存性
が強いためである.一般に,write 関数の中で,対応する write システムコール命
令が発行される.図 10.1(e) はシステムコールの窓口である.write システムコー
ルを契機として,ファイルを統一的に扱うOS機能が実行され,出力がバッファ
リングされる(後述するバッファ処理).ユーザプログラムから見ると,この時
点で表示処理は終了し,printf を呼び出した階層へ順次復帰する.
後者(2)のためには,自分のプログラムの出力を制御する階層と,複数の
プログラムからの表示要求を調停して順にデバイスに送る階層を設ければよい.
write システムコールが呼び出すファイル管理機能(図 10.1(f))が,出力先のデ
バイス(表示デバイスかファイルか)に依存しない形で,表示要求を一時蓄える
バッファ処理を行う.次に,出力先が表示デバイスの場合,ハードウェア制御プ
Proprietary & Confidential
コンピュータアーキテクチャの巻
10 章 オペレーティングシステムの役割
123
main:
:
call new_function
main:
:
new_instruction
main:
:
new_instruction
特権モードへ移行
OS命令列
例外検出入口
(未実装命令検出)
:
命令列で表現
return_from_例外検出
ライブラリ
(ハードウェアが直接実行)
new_function:
:
return
(a) ライブラリによる新機能の実装
(b) 命令による新機能の実装
(高性能ハードの場合)
(c) 命令による新機能の実装
(低コストハードの場合)
図 10.3: ハードウェアの補完
ログラム(デバイスドライバ )を呼び出して文字を出力する(図 10.1(g)).
以上が一般的な階層構造である.このうち,(c) と (d) はライブラリ中に含ま
れる機能である.コンパイラは,ソースプログラム (a) から命令列 (b) を生成し,
リンカが printf や write を含むライブラリを結合してロードモジュールを生成す
る.そして,(e) はOSのカーネル機能, (f) はOSのファイル管理機能,(g) は
OSのデバイスドライバである.すなわち,ユーザプログラムとOSとのインタ
フェースは,システムコールである(図 10.2).
10.2
OS機能の分類
複雑かつ動的な調整が必要な機能は,一度作ると修正できないハードウェアだ
けでは実現困難である.すなわち,高機能なコンピュータシステムには,ハード
ウェアの機能を補完し,プログラムに対して様々な高機能を提供するOSの存在
が不可欠である.以上に示した例も含め,OSの機能を大きく分類すると,次の
ようになる.また,次章以降,順に,プロセス管理,記憶階層,入出力機構,仮
想マシン,マルチコア管理機能について,詳しく説明する.
10.3
ハードウェアの補完
3 章 にて説明したように,CPU 毎に様々な命令が定義されている.しかし,通
常使用される演算のビット長が 4,8,16,32,64 と増加したり,表現方法の異
なる 10 進演算命令が登場するなど,命令の使われ方は時代とともに変化する.
CPU の設計者は,時代に対応すべく新しい命令体系を考案し続けているものの,
LSI の集積度が不足していたり,直ちに普及するとは考え難いので開発コスト低
コンピュータアーキテクチャの巻
Proprietary & Confidential
10.4. プロセス管理と特権モード
124
表 10.1: 代表的な特権命令
CPU 全体制御 割り込み先テーブルのアドレスを変更する命令
プロセス管理 プロセス ID に関する制御レジスタの内容を読み書きする命令
記憶管理
アドレス変換に関する制御レジスタや TLB を読み書きする命令
キャッシュに関する制御レジスタの内容を読み書きする命令
デバイスのレジスタを読み書きする命令
入出力管理
復帰命令
特権モードから復帰する命令(前述の return from sys call)
減を優先するなどの理由により,方向性は正しくてもハードウェア化を見送るこ
とがある.
このような場合,ソフトウェアライブラリとして機能を提供(図 10.3(a))す
るのではなく,将来ハードウェア化される前提(図 10.3(b))で命令を定義して
おくと,技術や需要が追い付いた時に,ライブラリを呼び出す手間を省いて効
率よく実行できる.具体的には,ハードウェアが未実装命令を検出した場合に,
CPU 毎にあらかじめ決められた番地の命令列を実行させる仕組み(例外検出と
呼ぶ機能の一部)を搭載しておく(図 10.3(c)).この命令列は,ユーザプログラ
ムではなく,OSの一部である.ハードウェア化されるまでの間,OSの命令列
が肩代りする.この考え方は,低価格・低機能ハードウェアと,高価格・高機能
ハードウェアにより同一の CPU シリーズを構成しつつ,いずれの CPU でも同
一のユーザプログラムを実行可能とする場合にも利用される.機能に差をつけな
いことでプログラムの可搬性を向上させ,価格差と性能差を連動させることで幅
広いユーザを獲得できる.
ハードウェアの故障に対する対策も重要である.主記憶の一部が故障して,特
定のアドレスに対する読み書きができなくなる場合がある.また,複数の CPU
を搭載するシステムでは,一部の CPU が故障する場合がある.いずれの場合も,
故障に起因する例外検出を契機として,OSが故障箇所を切り離してユーザプロ
グラムに使わせない仕組みとすることにより,システムの信頼性を向上させるこ
とができる.
10.4
プロセス管理と特権モード
プログラムとは,命令列とデータから構成される静的な状態であり,具体的には
ロードモジュールを指す.一方,プログラムが主記憶に配置され動作している状
Proprietary & Confidential
コンピュータアーキテクチャの巻