☆Linux
http://www.kernel.org/
◆ブート
①電源投入
②ROM BIOS動作
③IPL(Initial Program Loader)が動作、ブートストラップローダを起動
④ブートストラップローダがLinuxカーネルをメモリに読み込み、制御を渡す
⑤Linuxカーネルがハードウエア、ソフトウエアをチェック
_ メモリ、デバイス、ファイルシステムのチェックとカーネルの初期設定
⑥ルートファイルシステムをマウント
⑦Linuxカーネルが最初のプロセス(init)に渡す
_ initのPIDは「1」
カーネルは、システムコールなどが呼び出されるか、initが終了しない限り何もしない。
⑧RunLevelを設定する
_ /etc/inittabのinitdefaultに従う
⑨rc.Sを実行
⑩デフォルトRunLevelの実行
⑪デフォルトRunLevelのための設定
⑫ログインプロンプトの表示
※Linuxカーネルの在り処
/にあるvmlinuz (Ubuntu)
実体は/bootの下
_◇ローダー
MBRに設定し、起動用のラベルを入力することで、指定のOSを起動する。[TAB]を押すことにより登録されているラベルのリストが表示される。
※最大16個のOSを登録できる。
①LILO (Linux Loader)
ハードディスクのセクタを決めうちしてアクセスする。カーネル再構築を行ったあとに/sbin/liloを実行し忘れるとカーネルの絶対位置が判別できなくなる。
②GRUB (GRand Unified Bootloader)
カーネルのファイル自体にアクセスする。
_◇カーネルファイル
vmlinux
※実際には、vmlinuxをgzipによって圧縮かけたvmlinuzというファイルがブート用のカーネルファイルであり、/bootの配下におかれる。
(なお、さらにバージョン番号などが実ファイル名にはつくので、リンクが張られる)
※vmlinuzをfileコマンドで識別すればブートセクタ、vmlinuxをfileコマンドで識別すれば実行ファイルとして素性を確かめることができる
_◇Run Level
システムのメンテナンスなど通常と異なるモードでシステムを動作させるために、必要に応じてシステムサービスのセットを切り替えられるようにする仕組み。ディストリビューションにより定義は異なる。
_ /etc/inittab
に記述される。
※確認用のコマンド
runlevel
chkconfig
※代表的な定義
0 システム停止状態
1 シングルユーザモード
2 マルチユーザモード (NFSによるexport不可)
3 拡張マルチユーザモード(NFSによるexport可)
4 SlackwareではX Window System使用
_ RedHatでは未使用
5 RedHatではX Window System使用
_ Slackwareでは未使用
6 リブートモード
7 Slackwareではシステムブート時
_ RedHatでは未使用
_◇カーネルパラメータ
LILOからのブート時にカーネルにパラメータを渡すことで特定の機能のON/OFF等が行える。
※一覧のありか
Documentation/kernel-parameters.txt
※OSブート後は、/proc/cmdline で参照できる
※ケースセンシティブ
例)
LILO: linux single
_ シングルユーザモードで立ち上げる。パスワードの再設定が可能。
LILO: linux root=/dev/hda8
_ ルートファイルシステムを指定する。
※Linux2.6以降のビルドによっては、カーネルコンフィグレーションの内容をvmlinuz内に保存しておくことができる。
vmlinuzをgzipで解凍し、抽出したvmlinuxから
_ IKCFG_ST
_ IKCFG_ED
で囲まれた領域をさがせば、格納されているバイト列が見つかる。
_◇カーネルメッセージ
ブート時のハードウエアスキャン結果などは
_ dmesg
で確認できる
◆LP32/LP64
LP32
_ longとポインタが32ビット
_ Linux 2.4.22/glibc 2.2.5/i686
LP64
_ longとポインタが64ビット
_ Linux 2.2.20/glibc 2.2.5/aopha
_◇システムデータ型
_ 意味 LP32 LP64
caddr_t 仮想アドレス u4 u8
clock_t システムクロック u4 u8
dev_t デバイス番号 u8 u8
gid_t グループID u4 u4
ino_t i-node番号 u4 u4
mode_t ファイルモード u4 u4
nlink_t リンクカウント u4 u4
off_t ファイルオフセット s4/s8 s8
pid_t プロセスID s4 s4
rlim_t リソース上限 u4 u8
size_t サイズ u4 u8
ssize_t サイズ s4 s8
time_t UNIXepochからの秒数 s4 u4
u4 符号なし32ビット整数
u8 符号なし64ビット整数
sはそれぞれ符号付き
◆Linux カーネル
カーネル空間ではプリエンプティブではない
※ELF形式でビルドされ、vmlinuxというファイル名になる
※bootにおかれるのはvmlinuxを圧縮した
_ vmlinuz
_◇Kernel Archives
http://www.kernel.org
_◇履歴
2.2.26 2004/2/25
2.4.36.6 2008/6/6
2.4.36.7 2008/9/7
2.6.26.1 2008/8/1
2.6.26.2 2008/8/6
2.6.26.3 2008/8/20
2.6.26.5 2008/9/8
_◇ブートフラグ
ファイル先頭から0x1FEに0xAA55
ファイル的には bootsect.S
_◇シングルプロセッサとマルチプロセッサ
Linuxのシングル・プロセッサ向けのカーネルを使ってマルチプロセッサ環境のPCではブートできない。マルチプロセッサ向けにビルドが必要。
_◇プロセッサ種別名称
i386
_ 80386以降
i486
_ 80486以降
i586
_ Pentium
i686
_ PentiumPro, PentiumII, PentiumIII, Pentium4
ia64
_ Itanium, ItaniumII
x86_64
_ Opeteron, Athlon64, Xeon
_◇モノリシック・カーネル
monolithic
カーネル空間ではメモリが共有される。
カーネル内のモジュールが、他のモジュールのメモリを書き換えられる。
_◇特権レベル
x86の特権レベル0と3しか使用していない
_◇コンテキスト
カーネル空間で、複数のコンテキストは、メモリ空間を共有しつつ、独立に動くのでリソースの競合を管理しないとならない。
※ユーザー・コンテキスト
ユーザー空間から呼び出される。
システムコール⇒カーネルインタフェースからカーネル機能
システムコールが終わるまでユーザープロセスはブロックされる。
システムコールを使わない「ライブラリコール」ではカーネルに処理がわたらないのでユーザー・コンテキストは発生しない。
※割り込みコンテキスト
ハードウエア割り込み⇒割り込みハンドラ
割り込み処理は優先度が高く、他のユーザーコンテキストに割り込んで処理される。
_◇セマフォ
semaphore
クリティカル・セッションに入る直前でセマフォを取得し、クリティカル・セッションを出た後にセマフォを解放する。
※他がセマフォを獲得済みだった場合、そのコンテキストはスリープする。他がセマフォを解放するとスリープからウエイクアップされ、セマフォを獲得できる。
※バイナリセマフォ
※セマフォの初期化
セマフォ変数の初期化関数
void init_MUTEX (struct semaphore *sem);
※セマフォの獲得
void down(struct semaphore *sem);
_ P操作(カウンタをダウン)を行う。
_ スリープに入った場合、シグナルを送っても受け付けない。セマフォが解放されないと絶対にkillできないユーザープロセスが出来てしまう。
void down_interruptible(struct semaphore *sem);
_ P操作を行うが、シグナルを送ることができる
_ セマフォを獲得すると0を、シグナルを受信すると-EINTRを返す
※セマフォの解放
void up(struct semaphore *sem);
_ V操作(カウンタをアップ)を行う。スリープしているプロセスをウエイクアップさせる
※セマフォは割り込みコンテキストでは使えない。(割り込みコンテキストは最優先なので、割り込みコンテキストでスリープに入ると、ウエイクアップかからずストールする)
_◇割り込み
割り込みの禁止と許可のマクロ
local_irq_disable() 実体はCLI
local_irq_enable() 自体はSTI
※__volatile__属性の上、”memory”指定がされている。
⇒メモリ・バリア gccの最適化によりメモリ配置の順番が入れ替わらないようにする
割り込みステータスをセーブしての禁止と許可のマクロ
local_irq_save()
local_irq_restore()
※割り込み禁止のクリティカルセッションは可能な限り少なくすること
※クリティカルセッション中でスリープすると誰も起こしてくれないことになる
_◇SMP環境での割り込み
_◇カーネルログ
※カーネル内でのロギング
⇒printk関数
printfと類似だが、最初の引数としてログ・レベルを持つ
KERN_EMERG <0> 緊急メッセージ
など
※ログバッファにはsyslogシステムコールを通じてログバッファを読み取ったり、バッファを制御することができる
⇒glibc2.0ではklogctl関数による
※/proc/sys/kernel/printk
により、printkのログレベルなどを知ることができる
⇒カーネルからのメッセージをコンソールに表示する場合
echo 7 > /proc/sys/kernel/printk
(多分6を書き込むとコンソールへの出力をオフする)
◆プロセス
Linuxでは、実質的にTSSを使っていない
_◇プロセス構造体 (Linux2.6)
※thread_info構造体
_ スタック領域とあわせ THREAD_SIZE なる定数でサイズが決定される(例:8KB)
_ 構造体は、からならず THREAD_SIZE バイト境界に配置されるので、%espレジスタの THREAD_SIZE 分の下位ビットをマスクすることで先頭アドレスを得ることができる。
※task_struct構造体
_◇RunとSleep
Sleep 待機中 I/O待ちなどタイムスライスを得ることができない状態
⇒プロセスはブロック。イベント待ち。
Run 実行できる状態。タイムスライスを得ることができるが、OS次第。
_◇デーモン daemon
制御端末を持たず、特定のリクエストを待ち、リクエストがあれば子プロセスをforkする。親プロセスはまたリクエスト待ちに入り、子プロセスは処理を行い、終われば親プロセスに戻る。
①スタンドアロンサーバー
リクエストを直接受け付けて起動する
_ telnetd, ftpd, httpd
②スーパーサーバー
各デーモンを統括するスーパーサーバーがサービス要求を監視し、特定の要求を検出したらそれぞれのサーバを起動する。
_ inetd, xinetd
_◇ユーザプロセス
※フロントプロセス
※バックグラウンドプロセス
_◇プロセス管理用コマンド
ps
ps axH
_ 現在のシステム上のすべてのプロセスとスレッドを見る
_◇プロセスID
Process ID
システム上の全プロセスに対して重複しないように振られている通し番号。ある特定のプロセスを一意に指定できる。
※PID
_◇ゾンビ
zombie process
defunct
※親がfork()、子が_exit()、親がwait()で終了ステータスを受け取る
⇒親かwait()をしないまま動作しつづけた場合、子のステータスコードを保存するために、子プロセスは zombie となる。
※ゾンビ回避の方法
①fork()したらwait()する
②ダブルfork
_ 途中に余分なfork()をはさむ
_ ⇒親から子へ、子から孫を起動する
_ 孫が起動したかったプロセス。
_ 子は即座に終了させる。
_ wait()できるのは直接の親だけなので、孫プロセスを
_ wait()できるものはなく、孫は終了してもゾンビには
_ ならない
③sigation()
_◇プロセスツリー
initを根本とするツリー構造になっている
pstreeコマンドで表示される
_◇セッションとプロセスグループ
session
process group
※全てのプロセスは唯一つのプロセスグループと、セッションに所属している
※プロセスグループは、シェルからパイプとして起動されたプロセス群をまとめて操作できるようにしたもの。
※セッションは、ログインシェルを起点にユーザが同じ端末から起動したプロセスを1つにまとめる
⇒セッションと関連付けられた端末をプロセスの制御端末という。
※ps コマンドの j オプションでセッション、プロセスグループを見ることができる
※セッションリーダー
PID=SIDのプロセス
※プロセスグループリーダー
PID=PGIDのプロセス
※リーダーは最初にプロセスグループを作ったプロセスだが、新しいプロセスグループを作れない
_◇デーモンプロセス
deamon process
制御端末を持たないプロセス。制御端末がないので、端末がログアウトしても動作を続ける
※setsid(2)で作る
_◇/proc
※ /proc//maps
のプロセスのマップ
※ /proc/self/maps
自分のプロセスのマップ
◆スレッド
アプリケーションにおいて、メモリ空間を共有する複数のスレッドを並行に走らせることができる。
※カーネル内部でもカーネルスレッドを起動することは可能であるが、各コンテキストは1本筋のことが多い。
_◇排他制御
クリティカルセッションの排他制御
◆メモリ
_◇Linuxメモリマップ
32ビットアーキテクチャのプロセッサでは、4Gバイトの仮想アドレス空間を使用する(MMU必要)
※「オフセットアドレス」
オフセットアドレスを境に上位がカーネル空間、下位がユーザ空間
①x86, PowerPC, ARM
オフセットアドレス=0xC000 0000
②MIPS, SH
オフセットアドレス=0x8000 0000
※ユーザー空間とカーネル空間の橋渡しをするのがデバイススペシャルファイル
※x86
アドレス0から始まる大きなセグメント内でページング。仮想アドレス=リニア・アドレス
_◇アクセス管理
アクセスの禁止されているページへのアクセス
⇒カーネルはプロセスにシグナル SIGSEGV をおくる
⇒segmentation fault
※NULLポインタ参照は確実にsegmentation faultとなる
⇒カーネルは意図的に論理アドレスの最初の数ページをアクセス禁止とし、物理アドレスを割り当てない
_◇メモリマップトファイル
ファイルをメモリにマッピングし、メモリとしてアクセスできるようにする。
⇒システムコールmmap()による
⇒アクセスがあった時点でカーネルがファイルをメモリによみ、そのメモリを論理アドレスに対応付ける
⇒プロセスが使い終わったら、メモリの内容を書き戻す(論理、物理の関係もきれる)
_◇共有メモリ
特定範囲の物理メモリを複数プロセスで共有する
⇒1つの物理ページを2つのプロセスの論理アドレスに対応付ける。
※API
_ mmap()
_ POSIX shm
_ System V IPC
_◇プロセスのアドレス空間
①text領域
_ 機械語のプログラムの配置された領域
②data領域
_ グローバル変数のうち初期化済のもの
_ スタティック変数のうち初期化済のもの
_ 文字列リテラル
_ などが配置される
③BSS領域
_ グローバル変数で初期化が必要ないもの
_ ステティック変数で初期化が必要ないもの
_ ⇒サイズのみ
④heap領域
_ malloc()が管理する領域
⑤stack領域
※プロセスIDがnのプロセスのメモリ配置は、
/proc/n/maps
をcatすれば見ることができる
⇒対応するファイルがない領域にスタックやヒープがある
⇒スタックは伝統的に実行可能なので、古いカーネルでは実行できる「x」属性がついている。新しいカーネルではバッファオーバーフローをふせぐため実行できないようになっていることもある。
_◇EDAC
Error Detection And Correction
パリティエラーを検出、通知する機能
メモリECCおよびPCIバスのパリティを検出
※bluesmoke
※ECCパリティ時には、MCH(Memory Controller Hub)のレジスタに詳細が示されNMIがあがる。EDACはNMIで起動する
⇒1ビット訂正可能⇒ウォーニング
⇒訂正不可能⇒カーネルパニック
_◇メモリ確保の方法
①グローバル変数、スタティックな変数
⇒ビルド時に判明したサイズをBSS領域から取る
②ローカル変数
⇒ビルド時に判明したサイズを実行時にスタック領域からとる
③malloc()
⇒実行時に決まるサイズをヒープ領域から取る
④alloca()
⇒実行時に決まるサイズをスタック領域から取る
◆ファイルシステム
_◇広義のファイル
①regular file
内容がそのまま記録されているファイル。狭義のファイル。
②directory
他のファイル情報を複数入れることができるファイル。UNIXではディレクトリデータも単なるバイト列として読めたが、Linuxでは禁止している
③symbolic link
他のファイルの名前を格納したファイル。ソフトリンク。
カーネルがリンク先のファイルへのアクセスに自動的に置き換える。
④device file
デバイスをファイルとして表現したもの
※キャラクタデバイス
character device
好きなときに好きなところにはアクセスできない。データに順序がある。
※ブロックデバイス
block device
好きなときに好きなところにアクセスできる
⑥named pipe
名前付きパイプ。プロセス間通信用
⑦Unix domain socket
プロセス間通信で使う。TCPソケットでも同様なことができる。
_◇mount
ハードディスク
_ partitionで区画わけされ、それぞれの上にファイルシステムが構築される
_
⇒それぞれのファイルシステムをマウントすることで1本のディレクトリツリーに構成される。
_◇シンボリックリンク、ハードリンク
①ハードリンク
ファイルの中身に対してのリンク。リンク元とリンク先は対等。どちらも同じファイルの内容を指す。一方を削除しても他方はファイルを指し続けるので、内容にアクセスできる。
※i-node参照なので、ファイルシステムを跨げない
⇒端的に言えば、ファイルに新しい別名をつけることになる
⇒実体なので、ディレクトリにはつけられない
例)
$ ln a b
ファイル a の実体に b という名をつける
⇒ls -lでリンクカウントを確認することができる
②シンボリックリンク
ファイル名あるいは、ディレクトリ名に対するリンク。リンク元を削除してしまうと、リンク先はリンク元のファイルへアクセスできない。
※しかし、名前だけのリンクなので、ファイルシステムを跨げる
⇒名前に名前を結びつける。実際にシンボリックリンクにアクセスがあったときに実体を割り出す
⇒実体がなくてもとりあえず作ることができる
⇒ディレクトリにもシンボリックリンクは張れる
_◇パーミッション
permission
d rwx rwx rwx
d: ディレクトリか -:ファイルか
左のrwx 所有者
真ん中のrwx グループ
右のrwx その他(別グループのユーザ)
※umask 初期設定値
mkdir(), open()で作成するファイルのパーミッションをmodeで指定するが、umaskを使ってビットが落とされる。
⇒umaskで指定したビットが落ちる
mode & ~umask
例)modeが0777でumaskが022なら、実際は0755となる
※8進表記
r=4, w=2, x=1で合計すれば8進で表記できる
例)
rwxr-xr-x 755
絶対モード8進表現
— 0
–x 1
-w- 2
-wx 3
r– 4
r-x 5
rw- 6
rwx 7
※ディレクトリのパーミッション
r … 中のファイルをリストできる
w … 新しいファイルを作成したり削除できる
x … アクセスできる
ディレクトリが実行可能になっていないと、パーミッションにかかわらず内部のファイルにアクセスできない.
(x権限がないとファイルのiノード番号が分からない)
⇒ディレクトリのx権限だけあれば、内部のファイルにアクセスできる。中のファイルに対するr権限があれば、直接名前を指定して読み出すことはできるが、ディレクトリのlsはできない、というようにできる。
_◇スティッキービット
元は実行ファイルの高速化のためのビットであったが、現在のLinuxでは、ディレクトリに対するアクセス制御に使わる。
※スティッキービットがセットされているディレクトリに対する変更、削除は、ファイルの所有者、ディレクトリの所有者、スーパーユーザに限られる。
⇒皆で共有する/tmpデイレクトリにつけられる。
誰もが読み書きできるが、権限のない他人に消去されたりしないため。
スティッキービットの設定
$chmod 1777 tmp
$chmod +t tmp
_◇スペシャルファイル
ハードディスクなどのブロックデバイスをスペシャルファイルとして扱う。スペシャルファイルはファイルサイズ0のファイルであり、目的の機器を特定するためのポインタとなる。
※IDE
_ /dev/hd[a][1]
_ 1台目、2台目と a, b, c…となる
_ 第1パーティション、第2と 1, 2, 3…となる
※SCSI
_ /dev/sd[a][1]
_ 1台目、2台目と a, b, c…となる
_ 第1パーティション、第2と 1, 2, 3…となる
※伝統的UNIX
予め全てのデバイスファイルを作っておく
※devfs (Device File System)
システムに存在するデバイスのデバイスファイルだけをその都度作成する
⇒Linux 2.4以降
⇒USBとの相性がよくない
※udev
カーネルの外に実装された
⇒Linux 2.6以降
_◇ファイルシステムの形式
FAT File Allocation Tables
_ MS-DOS
VFAT Virtual File Allocation Tables
_ Windows95
VFAT32 Virtual File Allocation Tables32
_ Windows98
NTFS New Technology File System
_ WindowsNT, WIndows2000, WindowsXP
HFS Hierarchical File System
_ MacOS
HFS+ Hierarchical File System Plus
_ MacOS
ext Extended File System
_ Linux
ext2 Second Extended File System
_ Linux
ext3
ReiserFS
HPFS High Performance Filesystem
_ OS/2 Warp
XFS
_ SGI提供
JFS
_ IBM提供
_◇ext2
※1K~4KBのブロックで管理
※ディスク
_ ブートブロック
_ ブロックグループ
_ 管理情報(ブロックの使用、未使用)
_ i-nodeテーブル
_ データ本体
※i-node
_ モード(アクセス権)
_ ユーザID
_ サイズ
_ 最終アクセス時刻
_ 直接参照ブロック
_ 間接参照ブロック
_ 2次間接参照ブロック
_ 3次間接参照ブロック
→データは、各参照ブロックからのポインタでたどれる
直接参照できるのは12ブロックまで
→ファイル名はi-nodeにはなく、データブロックの中のディレクトリデータ内に、ファイル名とi-nodeインデックスという形で格納されている
⇒よって複数のディレクトリエントリに同じi-nodeインデックスを割り当てることで、ハードリンクを張ることができる。(ハードリンクの場合、i-nodeを参照する全ディレクトリエントリが削除されないとi-nodeは削除されない)
※シンボリックリンク
新たにファイルを作り、データとしてリンク先への参照(ディレクトリエントリへの参照)を記述する。リンク先のディレクトリエントリが消えると、参照できなくなる
_◇擬似ファイルシステム
pseudo filesystem
後ろ盾にするデバイスが存在しない
①procfs
Process File System
/procにマウントされる
プロセスをファイルシステム上に表現するしかけ
例)
PID=1のプロセス情報
/proc/1
エントリの内容はcatコマンドなどで得られる
⇒カーネルの情報も /procにある
※変更すると、カーネルに何かを指定することになるものがある。
②tmpfs
③devfs
Linux 2.4~の/dev
Linux 2.6~はudev
_◇ディレクトリ構成
directory tree
※ディレクトリツリーの標準規格
FHS The Filesystem Hierachy Standard
※旧規格
(FSSTND Linux Filesystem Structure Standard)
/ (root)
_ bin コマンド類
_ システムの基本コマンドをおく
_ boot 起動時に必要なスタティックリンク
_ Linuxカーネル vmlinuz
_ dev デバイス・スペシャルファイル
_ etc マシン毎の設定ファイル
_ X11 X関連設定ファイル
_ home ユーザのホームディレクトリ
_ 必ずしも/homeだけではない。
_ /home2…など
_ $HOME
_ lib 共有ライブラリ
_ ディストリビューション管理
_ mnt マウントポイント
_ proc プロセス、メモリ情報などシステム使用
_ (プロセスファイルシステム)
_ root スーパーユーザーホーム
_ sbin システム管理用コマンド
_ ブート時に必要なもの
_ temp 一時ファイル
_ tmp 一時ファイル
_ リブートしたら消える可能性がある
_ usr ユーザー利用階層
_ 基本的に複数のマシンで共有可能な
_ ファイルをおく
_ ⇒ネットワーク越しにマウントできるよう
_ User Services and Routines
_ X11 X11コマンド
_ X11R6 X Window Systemのルート
_ bin システム標準以外のコマンド
_ ディストリビューション管理なので
_ 自分でインストールするものはlocalに
_ いれるのがよい
_ doc 各種ドキュメント
_ local システム標準以外のプログラム
_ 各システムの管理者が管理する
_ bin ローカルなbin
_ lib ローカルなlib
_ man マニュアルファイル
_ sbin 標準以外の管理コマンド
_ 平常時のシステム管理
_ サーバプログラム
_ src カーネル、ソースファイル
_ (システムで使っているもの)
_ lib ライブラリ
_ ディストリビューション管理
_ include システムヘッダファイル
_ share アーキテクチャ非依存
_ 共有可能なファイル
_ 例)ドキュメントなど
_ man manページ
_ info infoのデータ
_ var 可変データ
_ そのマシン固有のデータをおく
_ 共有するファイルはおくべきでない
_ spool mailやプリンタの入出力の一時保存
_ run 起動中のサーバプロセスのPID
_ log サーバプロセスが書き込むログ
_ tmp 一時ファイル
_ リブートしても消されない
※マウントポイントは、ユーザが独自に作っても良い。
◆ストリーム
byte stream
ファイルディスクリプタで表現され、read()やwrite()システムコールで扱えるもの
※FILE型の値
ストリームを操作するときに使うデータ構造
※カーネルモジュールでは
STREAMSというモジュールが使われる
_◇ファイル
_◇デバイス
_◇パイプ
プロセスからプロセスにつながるストリーム
ファイル同様、ファイルデスクリプタで表現される
※1つのパイプは一方向
_◇ネットワーク通信
_◇プロセス間通信
※ストリームを使わないプロセス間通信
System V IPC
_ セマフォと共有メモリとメッセージキュー
_◇ファイルディスクリプタ
file descriptor
単なる整数値(int)であるが、カーネルが持っているストリームを管理するデータ構造と一対一に対応している
※ファイルディスクリプタとFILE型を安易にまぜて使うと、stdioのバッファを介したり、介さなかったりすることになり、入出力の順序がおかしくなる
※FILE型でできない操作のときに直接ファイルディスクリプタを併用するのがよい。
①新たなファイルにパーミッションを指定する
open()でファイルを開く
fdopen()でFILE型を作る
②ioctl()などの操作が必要
_◇標準入出力
シェルからプロセスが起動された場合、用意されているストリーム
①標準入力
standard input
ファイルディスクリプタ0番 STDIN_FILENO
②標準出力
standard output
ファイルディスクリプタ1番 STDOUT_FILENO
③標準エラー出力
standard error output
ファイルディスクリプタ2番 STDERROR_FILENO
_◇Linuxにおける行
①特定の文字 \nまで
②ファイルの最後、ストリームの末尾
◆シグナル
signal
シグナルの実体はint型の整数であり、カーネルがプロセスに何かを通知するために使う
※プロセスで特に設定をしていないと配送されたシグナルはカーネルが処理する(シグナルの種類による)
①無視する
②プロセスを終了させる
③コアダンプして異常終了させる
例)
子プロセス終了のSIGCHLD。。。無視
ターミナルからの^C
⇒カーネルが該当プロセスに SIGINT を送る
⇒受け取ったプロセスが自発的に終了する
SIGSEGV⇒Segmentation faultによる異常終了
※プロセスはシグナル受信時の挙動を変更することができる
_◇シグナル
SIGINT
_ ^Cによる割り込み。通常はプログラム中止
SIGHUP
_ ユーザログアウト。通常はプログラム中止
_ デーモンプロセスでは設定ファイルの読み直し
SIGPIPE
_ 切れたパイプに書き込んだ。
_ 通常はプログラム中止。
SIGTERM
_ プロセス終了させる。killのデフォルト。
SIGKILL
_ 確実にプロセスを終了させる。
_ ⇒プロセスでの捕捉はできない
SIGCHLD
_ 子プロセスの終了。
_ 通常は無視
SIGSEGV
_ 禁止メモリへのアクセス。
_ 通常はコアダンプして終了
SIGBUS
_ アライメント違反
_ 通常はコアダンプして終了
SIGFPE
_ 算術計算エラー
_ 通常はコアダンプして終了
_◇コアダンプ
core dump
◆ドライバとデバイス
_◇PCIの規格
①PCI Conventional
バージョン1.0から3.0まである
32ビット、64ビット幅
33MHz/66MHz
※PCIの「スロット」としては32ビット,33MHzが一般
②PCI-X
③PCI Express
x1, x4, x8, x16
_◇バス番号、デバイス番号、ファンクション番号
バス番号 0~255
_ 複数のPCIバスを識別するため
デバイス番号 0~31
_ バス上のデバイスを識別するため
ファンクション番号 0~7
_ デバイス内のファンクションを識別するため
※バス0には、ホストバスがホストブリッジを介して接続
※AGPバスなどに実装してあるビデオカードも論理的にはPCIデバイスとして認識させる
※表示形式
_ XX:YY.Z
_
_ XX バス番号
_ YY デバイス番号
_ Z fannkushonn
_ banngou
_
※PnP対応
デバイスへのIRQ,DMAなどのリソース割付を自動化し、デバイスドライバのロードも自動化する
※バスウォーク(バス・スキャン)
ブート時にPCIコンフィグレーション空間からベンダIDを読み出して無効値(FFFFh)なら未実装、そうでなければ実装とする。
_ ①バス、デバイス、ファンクション番号を総当りでチェックする
_ ②バス番号0からPCIブリッジを基点に再帰的にサーチする
_◇PCI IDとコンフィギュレーション空間
PCIデバイスの識別(PCI-ID)
_ ベンダID 2バイト
_ デバイスID 2バイト
/usr/share/hwdata/pci.ids
※The Linux PCI ID Repository
http://pciids.sourceforge.net/
※IA-32におけるPCIコンフィギュレーション空間
①コンフィグレーション・メカニズム1
_ IO=0CF8hにCONFIG_ADDRESSを書き込む
_ bit31 Enable bit(1にする)
_ Bit30-24 予約
_ bit24-16 bus番号
_ bit15-11 device番号
_ bit10-8 function番号
_ bit7-2 registerアドレス
_ オフセットは4バイト境界
_ bit1,0 00
_ IO=0CFCh~0CFFhに、必要なバイト分アクセスする
_ 4,2*2,1*4バイト
②コンフィグレーション・メカニズム2
_ レガシーな方法
_◇PCI BIOS
呼び出し方法
①16ビット・リアル・モード
INT 1Ahを呼び出す
_ (000FFE6Ehをさしている)
②16ビット・プロテクト・モード
INT 1Ahを呼び出す
③32ビット・プロテクト・モード
PCI BIOSのメモリ領域からBIOS32サービスディレクトリを探し、そこにあるPCI BIOSルーチンを呼ぶ
_ E0000h~F0000hまでのシステムBIOS内で
_ オフセット サイズ
_ 0 4 シグネチャ _32_
_ (文字列先頭より)
_ 4 4 PCI BIOSへの32ビットポインタ
_ 8 1 00h
_ 9 1 01h
_ 0Ah 1 チェックサム
_ (加算すると0)
_ 0Bh 5 0
エントリポイントは物理アドレスなので、LINUXからはカーネル仮想アドレスに変換して呼び出す必要がある
※/arch/i386/pci/pcbios.cに検出コードがある
※PCI BIOS32サービス
しかるべきレジスタをセットして、BIOS32サービスディレクトリのエントリポイントを関数コールすることで、特定のPCI BIOS32サービスが実装されているか、否か、実装されている場合は、エントリポイントがわかる
_◇procファイルシステム
procfs
仮想ファイルシステム
デバイスにアクセスできる
※PCIデバイス
/proc/bus/pci
にバス番号を名前とするディレクトリがあり、そのなかに
_ デバイス番号.ファンクション番号
というファイルがある。
※hexdumpでダンプするとPCIコンフィギュレーション空間が読める。
※割り込み
/proc/interrupts
catでみれば、割り込み番号と接続、発生回数を読める
XT-PIC
_ 8259A
APIC(Advanced Programmable Interrupt Controller)
SAPIC(Streamlined APIC)
_ IA-64向け
_◇sysfsファイルシステム
procfsのツリー構造が無秩序なため、Linuxカーネル2.6以降で実装された
※PCIデバイス
/sys/bus/pci
_◇lsmod
ロードされているドライバの一覧
ただしこれでは、デバイスとドライバの関係は分からない。
# /sbin/lsmod
_◇lspci
lspci PCIデバイスのリスト表示
バス番号等が分かれば以下のようにして、デバイス情報を得ることができる。
lspci -s 0000:02:0c.0
lspci -t ツリー表示
※AGP Accelerated Graphics PortデバイスもPCIデバイスとしてOSに見せることがある
※PCI ID
_ /usr/share/hwdata/pci.ids
に格納されている
http://pciids.sourceforge.net
_◇sysfs
デバイス・ドライバを「ツリー構造」として表示できる仮想ファイルシステム。
※Linux2.6以降
※/sys配下に
_ /sys/bus/pci/
のように展開されている
※lsmodに現れるドライバ名のディレクトリで ls すれば
0000:02:0c.0@
のように
_ バス番号2
_ デバイス番号12
_ ファンクション番号0
のPCIスロットに搭載されているデバイスを制御していることが分かる
_◇ドライバのビルド
Linux2.6以前
_ gcc -cでコンパイル、.oオブジェクトファイル
Linux2.6以降
_ .koオブジェクトファイル
※ドライバの組み込み
#insmod ./objectfile
※ドライバの取り外し
#rmmod ドライバ名(カーネルモジュール名)
◆ユーザ管理
カーネルが扱うのはユーザIDであって、ユーザ名は各プログラムが変換している
_◇設定ファイル
※UIDは/etc/passwd, /etc/shadowに格納される。
/etc/passwd
/etc/shadow スーパユーザのみ
※GIDは/etc/groupに格納される
/etc/group
※ユーザ情報は必ずしも passwd にあるとは限らない
NIS: Network Information Service
LDAP: Lightweight Directory Access Protocol
⇒複数のマシンでユーザ情報を共有
⇒ユーザ情報へのアクセスはAPIを使うべき
_◇グループ
※各ユーザは最低一つのグループに属する
⇒最初のグループ
useraddコマンドの -g オプションで作成する
※補足グループ
supplementary groups
複数のグループにユーザを追加することもできる
useraddコマンドの -G
vigrコマンド
_◇クレデンシャル
credential
プロセスの属性としてのユーザ
※login時に作成され、以後、自分がプロセスを起動する場合には、自動的にコピーされ、パーミッションと突合せが行われる
◆ターミナル
_◇仮想コンソール
virtual console
モニタやキーボードは1対しかなくても、Linuxの内部では複数の仮想コンソールが起動している
※仮想端末機能
CUI端末でログインしている場合、
Alt + F1 ~ F7で仮想端末を使える。
CTRL + Alt +
※X起動中は切り替えが禁止される場合がある
⇒通常Xは端末を1つ、多くはtty7を使う
_◇デバイスファイル
/dev/tty0 …最初の仮想コンソール
/dev/ttyS0 … 1番目のシリアル回線
_◇端末にかかわるライブラリ群
│ │process │
│ └┬────────────┬──┬┘
│ ↓ │ │
│ ┌┴──────────┐ │ │
│ │CURSES │ │ │
│ └┬─────────┬┘ │ │
│ ↓ │ │ │
│ ┌┴───────┐ │ │ │
│ │termcap/│ │ │ │
│ │terminfo│ │ │ │
│ └────────┘ │ │ │
│ ↓ ↓ │
│ ┌─────┴──┴┐ │
│ │termios │ │
│ └┬────────┘ │
│ ↓ioctl ↓ioctl
│ ┌─────┴──────────┴┐
│ │Kernel │
ioctl(2)
ストリームの先のデバイス特化システムコール
termios
libcの一部、ioctl()を抽象化
termcap/terminfo
端末に対して意味を持つバイト列もつデータベース
⇒Linuxではterminfoが基本
Curses
⇒Linuxではncursesが基本
◆ロケール
言語環境名(locale名)=language_territory.codeset
例)
_ ja_jp.ujis
言語=日本語、地域=日本、文字コード=日本語EUC
※引数なしでlocaleコマンドを実行することで調べることができる。
※bash
_ export LANG=C
_ 英語環境に設定
◆日本語環境
日本語入力システムはクライアントサーバ方式である。
_◇サーバ
jserver
cannaserver
_◇FEP
uum — jserver
canuum — cannaserver
_◇XIM X Input Method
xwnmo — jserver
kinput2 — jserver/cannaserver
_◇Mule
たまご(egg) — jserver
かんな/emacs — cannaserver
◆ポート制御
inetdにより、ポートの開閉を操作することができる。
※プログラムとポートの割り当て
/etc/services
_ 1st field サービス名
_ 2nd field ポート番号、プロトコル
_ 3rd field サービスエイリアス
#以下コメント
※/etc/inetd.conf
1行に1サービス. /etc/inetdの再起動によりコメントアウトされたサービスは停止
#以下コメント
service_name socket_type proto flags user server_path args
service_name サービス名称 /etc/servicesにあわせる
socket_type dgram/stream
_ dgram:受信確認せず、主にUDP
_ stream:信頼性高い、主にTCP
proto プロトコル名称
flags wait/nowait
user プログラム実行権限
server_path サーバプログラムのパス
args サーバプログラムに渡す引数
一般にtftp, finger, telnetなどをコメントアウトする
◆TCP Wrapper
inetd→tcpd→目的のサーバプログラム起動
tcpd
_ /etc/hosts.allow
_ /etc/hosts.deny
により、接続ホスト毎にサービスの提供の許可/不許可を決定
例)
_ in.ftpd:192.168.5.100 [,…]
ALL すべて
LOCAL 同じドメイン
PARANOID DNSのホスト,IPと異なるもの
EXCEPT 例外
※xinetdの場合、inetdとtcpdの機能を兼ねる
◆アクセスログ
/var/log/syslog
◆サーバ
①DNSサーバ
_ BIND Berkeley Internet Name Domain
_ djbdns
②WWWサーバ
_ Apache
③メールサーバ
_ sendmail
_ qmail
_ postfix
_ exim Debian標準
④FTPサーバ
_ wu-ftpd
_ Pro-FTPD
_ Pure-FTPd
_ NcFTPd
_ BetaFTPD
⑤データベースサーバ
_ Oracle
_ PostgreSQL
_ mySQL
⑤ファイルサーバ/プリントサーバ
_ NFS Network File System
_ Samba (Windows)
_ CAP Colunbia AppleTalk Package
_ netatalk (Mac)
⑥プロキシ/キャッシュサーバ
_ Squid
⑦DHCPサーバ
_ ICS DHCPd
◆慣習
_◇コマンドラインオプション
①「-」で始まるコマンドライン引数はコマンドオプションと解釈する
⇒各コマンドによる。慣習に従わないのは、非常に古いコマンドであることが多い
②パラメータをとらないオプションは、1個のマイナス記号につづけて複数連続して書いてもよい
③パラメータをとるオプションは、オプション文字の次の引数にパラメータを与えてもよいし、オプション文字に連続して与えてもよい
④「–」ではじまるロングオプションを受け付けるものもある<>「-」はショートオプションと呼ばれる
⑤「-」を単独で用いると、標準入力から入力せよという意味になることがある
⑥「–」はここでオプション解析を停止せよ、という意味になることがある。
⇒マイナスから始まる文字列を引数として与えるため
◆TIPS
_◇bashからシリアルデバイスへの入出力
出力
$ echo xxx > /dev/ttyS0
入力
$ cat /dev/ttyS0
_◇割り込み回数の表示
cat /proc/interrupts
_◇crontab
指定日時、時刻にコマンドを自動実行できる。
_◇サーバーソフトなどを再起動する
kill -HUP PID
※サーバプロセスのPIDは /var/run/以下にテキストファイルとして記録されている
例)
/var/run/inetd.pid
シェルからは、“(バッククオート)で囲ってコマンドとして実行した部分をその出力で置き換える記法を使うと
kill -HUP `cat /var/run/inetd.pid`
とすれば、inetdにHUPシグナルを送ることができる
_◇システムの再起動
reboot
shutdown -r now
_◇システムの終了
halt
shotdown -h now
_◇ホスト名
/proc/sys/kernel/hostname
を読めば現在のホスト名が得られる。
⇒書き込むと変更できる
◆Unixマニュアルセクション構成
1 一般コマンド
2 オペレーティングシステム呼び出し
3 Cやその他の言語のライブラリ
4 特別なファイルとハードウエアサポート
5 ファイル形式
6 オンラインゲーム
7 その他の情報
8 システムの保守と操作のためのコマンド
9 カーネル内部情報