30
オペレーティングシステムの読み書き#1 2011/9/26 Nagoya geekbar

V6read#1

Embed Size (px)

Citation preview

Page 1: V6read#1

オペ―レーティングシステムの読み書き#1

2011/9/26

Nagoya geekbar

Page 2: V6read#1

UNIX/BSD/Linuxを読み解く

Lions本読書会に出てみた

本だけで読み解くのは大変

+簡単な解説で理解できる人は増えるはず

拙者のネタとしてGeekBarで毎週やってみる

名古屋にいないときは新横浜から

月1でぐだ生でも取り上げる

Page 3: V6read#1

教材 Lions Commentary on UNIX

ASCII Books 3990円

○ 原著OnLine版

○ http://v6.cuzuco.com/v6.pdf

○ http://www.lemis.com/grog/Documentation/Lions/book.pdf

On Line Manual pdf版

http://cm.bell-labs.com/7thEdMan/bswv7.html

Simh

PDP11のシミュレータ

V6,v7はedしか使えないので2.9BSDを用意 (viが使えます)

2.9BSDのカーネルはv7とほぼ同じ

Page 4: V6read#1

simh

古いコンピュータのシミュレータ

Ubuntuでは apt-get install simh

ドキュメントは /usr/share/doc/simh/pdp11_doc.pdf

pdp11のシミュレータの起動

$ pdp11

PDP-11 simulator V3.8-1

sim>

Page 5: V6read#1

2.9bsdの実行環境 - 準備

https://github.com/magoroku15/2.9BSD

Downloadsでtar.gzを落とす

展開

$tar xfovz Dounloads/magoroku15-2.9BSD-2fa33c4.tar.gz

$ls ~/magoroku15-2.9BSD-2fa33c4

root.dsk README bsd.ini home.dsk setup.ps

swap.dsk usr.dsk

自分でやってみたい人はhttp://gitter.matrix.jp/を参考にするよい

Page 6: V6read#1

2.9bsdの実行環境 – 使ってみる $ cat README

- How to start simh with this system in ubuntu.

pdp11 bsd.ini

- How to boot.

rl(0,0)rlunix

- How to change multiuser

^d

login: root

- How to quit shimh

# sync; sync; sync;

^e

sim> q

Page 7: V6read#1

なぜ2.9bsdを使うのか

v6, v7はエディタがedなので…….

コンパイラが吐くpdp11のアセンブラを眺めると雰囲気がわかる

仕様を理解する場合のリファレンスとして使う

Page 8: V6read#1

このあたり

Page 9: V6read#1

Commentary On UNIXに戻って

2 Fundamentals (PDFだとP4)

命令セット

9 Hardware Interrupt and Traps (PDFのP42)

割り込み

をちょこっとだけ

Page 10: V6read#1

Processor Status Word

Page 11: V6read#1

各ビットの内容 14,15 current mode (00 = kernel;)

12,13 previous mode (11 = user;)

5,6,7 processor priority (range 0..7)

4 trap bit

3 N, set if the previous result was negative

2 Z, set if the previous result was zero

1 V, set if the previous result gave an overflow

0 C, set if the previous operation gave a carry

Page 12: V6read#1

実はCPUはみな同じ 人気のある別のCPUの例 11 OF オーバーフローフラグ.符号付演算で桁あふれが発生した場合にセットされる.

10 DF ディレクションフラグ.ストリング操作命令においてポインタの増減方向を示す.

09 IF インタラプト・イネーブルフラグ.このフラグをクリアすると外部割込みを受け付けなくなる.

08 TF トラップフラグ.デバッガなどでシングルステップ実行するときにセットするフラグ.

07 SF サインフラグ.演算結果の符合をあらわす.演算結果が負になった場合にセットされ,正になった場合にクリアされる.

06 ZF ゼロフラグ.演算結果がゼロの場合にセットされる.

04 AF 補助キャリーフラグ.BCD演算で使われるキャリーフラグ(詳細については別途調べてね).

02 PF パリティフラグ. 演算結果の各ビットについて,1となるビットが偶数のときはセットされ,奇数のときはクリアされる. つまり,演算結果の各ビットの1の数とPFを足すと必ず奇数になるようになっている. パリティチェックの常套手段.

01 CF キャリーフラグ.演算の結果,桁上がりが生じた場合にセットされる.

Page 13: V6read#1

レジスタ r0, r1 are used as temporary accumulators during expression

evaluation, to return results from a procedure, and in some cases to communicate actual parameters during a procedure call;

r2, r3, r4 are used for local variables during procedure execution. Their values are almost always stored upon procedure entry, and restored upon procedureexit;

r5 Is used as the head pointer to a ``dynamic chain„‟ of procedure activation records stored in the current stack. It is referred to as the ``environment pointer''.

r6 (also known as ``sp'') is used as StackPointer

r7 (also known as ``pc'') is used asthe program instruction address register.

Page 14: V6read#1

CPUの処理

以下を繰り返す

PCから命令を読み

解析して

実行

実行の副作用として、PSWを書き換えたり、PCを書き換えたり、SPの示すメモリの内容を書き換えたりする

Page 15: V6read#1

誤解しやすい点

PCもレジスタの一種

比較と分岐は別命令

サブルーチンの呼び出・復帰

スタックに状態を退避・復元

Page 16: V6read#1

CPUが命令の実行に失敗したら?

たとえば

丌正なアドレスを参照した

未定義の命令を実行しようとした

0で割り算した

次の命令はどこから取り出せばよい?

Page 17: V6read#1

Trap “わな”を仕掛けておく

CPUが身動きが取れなかった場合に次に命令を取り出す場所を“わな”として仕掛けておく

Page 18: V6read#1

PDP11での“わな”の種類 Vector Location type priority

004 Bus timeout 7

010 Illegal instruction 7

014 bpt-trace 7

024 iot 7

034 power failur 7

114 emulator trap instruction 7

240 11/10 parity 7

244 floting point error 7

250 Segumentation violation 7

Page 19: V6read#1

“わな“のプログラム 1段目 unix/low.s

0500 / low core

0501

0505 br7 = 340

0506

0507 . = 0^.

0508 br 1f

0509 4

0510

0511 / trap vectors

0512 trap; br7+0. / bus error

0513 trap; br7+1. / illegal instruction

0514 trap; br7+2. / bpt-trace trap

0515 trap; br7+3. / iot trap

0516 trap; br7+4. / power fail

0517 trap; br7+5. / emulator trap

0518 trap; br7+6. / system entry

Page 20: V6read#1

“わな”のプログラム 2段目 0752 .globl trap, call

0753 /* -------------- */

0754 .globl _trap

0755 trap:

0756 mov PS,-4(sp)

0757 tst nofault

0758 bne 1f

0759 mov SSR0,ssr

0760 mov SSR2,ssr+4

0761 mov $1,SSR0

0762 jsr r0,call1; _trap

0763 / no return

サブルーチンコール。C言語のtrapを呼び、戻りる先はアセンブラのエントリcall1

Page 21: V6read#1

“わな”のプログラム 3段目 2693 trap(dev, sp, r1, nps, r0, pc, ps)

2694 {

2695 register i, a;

2696 register struct sysent *callp;

2697

2698 savfp();

2699 if ((ps&UMODE) == UMODE)

2700 dev =| USER; 2750

2702 switch(dev) {

2703

2704

2715 default:

2716 printf("ka6 = %o¥n", *ka6);

2717 printf("aps = %o¥n", &ps);

2718 printf("trap type %o¥n", dev);

2719 panic("trap");

2721 case 0+USER: /* bus error *

2722 i = SIGBUS;

2723 break;

2724

Page 22: V6read#1

3段目の処理 Location type USER KERNEL

004 Bus timeout SIGBUS panic

010 Illegal instruction SIGINS panic

014 bpt-trace SIGTRC panic

024 iot SIGIOT panic

034 power failur SIGEMT panic

114 emulator trap instruction SystemCall -

240 11/10 parity panic panic

244 floting point error SIGFPT SIGFPT

250 Segumentation violation SIGSEG panic

Page 23: V6read#1

大事な仕事 2751 case 6+USER: /* sys call */

2752 u.u_error = 0;

2753 ps =& ~EBIT;

2754 callp = &sysent[fuiword(pc-2)&077];

•PCは”わな”に落ちた命令の次のアドレス

•この命令は2バイトなので2を引いて

•プログラムも空間からword(2バイト)を読み

•下位6ビットを取り出す

•この値をindexにしてsysentを見ると

Page 24: V6read#1

sysent 2906 * to the appropriate routine for processing a system call.

2907 * Each row contains the number of arguments

2908 * and a pointer to the routine.

2909 */

2910 int sysent[]

2911 {

2912 0, &nullsys, /* 0 = indir */

2913 0, &rexit, /* 1 = exit */

2914 0, &fork, /* 2 = fork */

2915 2, &read, /* 3 = read */

2916 2, &write, /* 4 = write */

2917 2, &open, /* 5 = open */

Page 25: V6read#1

open systemcallのライブラリ globl _open, cerror

_open:

mov r5,-(sp)

mov sp,r5

mov 4(r5),0f

mov 6(r5),0f+2

sys 0; 9f

bec 1f

jmp cerror

1:

mov (sp)+,r5

rts pc

.data

9:

sys open; 0:..; ..

Page 26: V6read#1

/usr/include/sys.s indir = 0.

exit = 1.

fork = 2.

read = 3.

write = 4.

open = 5.

close = 6.

wait = 7.

creat = 8.

systent[]のindex

Page 27: V6read#1

System callの呼び出し

1. C言語で open(“aa”, 2)

2. Libcで sys 5 sysはemulator trap instruction

3. 3段目で 5を取り出して

4. sysent[5] カーネル内のopen処理を見つけ

5. Open処理を呼ぶ

Page 28: V6read#1

Trap/Interupt を理解する

OSの骨格を形成している

Page 29: V6read#1

次回は

引き続き trap/Interupt

Page 30: V6read#1

おわり