SlideShare a Scribd company logo
1 of 21
V7から始めるUNIX
        まとめ
予備知識であるCPUアーキテクチャのほん
 のさわりを説明したあと、本題に入ります
予備知識
• コンピュータ・アーキテクチャについて
 – 低レイヤのプログラムの理解に欠かせない
 – 理想を言えば、網羅的に知っておくことが好ましい
   • ハードとソフトは両輪だから
 – ただし、技術の範囲が広大すぎて、とてもここでは扱いき
   れない
 – 疑問が出た都度、身近な専門家に声をかけて聞くと、きっ
   と親切に教えてくれる!←学校か職場の専門家が誰か、
   把握しておこう!
   • 私も知っている範囲で答えます
 – ここではCPUの基本構成、マシン語から演算器で実行さ
   れる手順にフォーカスして、次ページ以降で少しだけさわ
   る

                                2
CPUの基本構成、超ざっくり
• 参考情報※の本文が、非
  常に素晴らしいので、そち
  らに詳細の解説はゆずり
  ます
   – CPUは大きく、演算部と制
     御部から構成されます
   – CPUにはメモリが接続され
     ています
   – ROMには、コンパイラに
     よってプログラムから変換
     され、CPUが実行可能な
     マシン語に変換されたデー
     タが入っています

※参考:http://homepage2.nifty.com/ttoyoshima/Computer/Config.htm
                                                          3
マシン語
• プログラム言語はコンパイラによってCPUが直接理
  解し実行できるマシン語に変換される
• マシン語は、CPUで処理される(命令パイプライン)
• マシン語の例
参考情報
http://www.geocities.jp/mori_imms/asmDetail.html
http://msyk.net/keio/JavaBook/ch1.html




                                                   4
命令パイプライン(1/2)
• 汎用パイプラインについて説明する
• 次ページの図は、一般化した次のような4段のパイプライン
  を示している。
• フェッチ (Fetch):メモリから機械語を取り出してくる動作
• デコード (Decode):機械語を解読し、制御信号を送る
• 実行 (Execute):実行する
• ライトバック (Write-back):実行結果をファイルかメモリに書き
  込む
• 次ページの図の上にある灰色の矩形には実行を待っている
  命令が並んでいる。下の灰色の矩形には実行が完了した命
  令が並んでいる。真ん中の矩形がパイプラインを表している。
• 実行は次ページのようになる。
参考:Wikipedia
                                   5
命令パイプライン(2/2)
    説明
0   4つの命令が実行されるのを待っている。
1   緑の命令をメモリからフェッチする。
    緑の命令をデコードする。
2
    紫の命令をメモリからフェッチする。
    緑の命令を実行する(実際の命令処理を行う)
3   紫の命令をデコードする。
    青の命令をフェッチする。
    緑の命令の結果をレジスタファイルかメモリに書き込む
    紫の命令を実行する。
4
    青の命令をデコードする。
    赤の命令をフェッチする。
    緑の命令は完了した。
    紫の命令の結果を書き込む。
5
    青の命令を実行する。
    赤の命令をデコードする。
    紫の命令は完了した。
6   青の命令の結果を書き込む。
    赤の命令を実行する。
    青の命令は完了した。
7
    赤の命令の結果を書き込む。
8   赤の命令は完了した。
9   全命令を実行した。
                                6
• 示した例は、一般的な例です
• 実際はもっと複雑で、いろいろ工夫されてい
  ます
• 気に入っている、または気になるチップの
  アーキテクチャを調べていくと、楽しいです
 – チップメーカーは大抵、開発者向けのホワイト
   ペーパーを出しています
 – わからない専門用語は、専門家に聞こう!
  • 私も知っている範囲で答えます

                           7
V7の理解(1/2)
• 現在のLinuxの原点はV7
  – V7→BSD→Linux
• V7を読み解くことで、原理の理解を進めることを
  目的とする
• 今回は、V7の理解の一環として、まず
  root/h/user.hとroot/sys/slp.cの実装を読み解い
  ていく
  – slp.cはスワッピングについて記載されており、プロセ
    ス制御の基本です
• 若干「わかっているつもり」な人向け

   参照したソースコード: http://www.tamacom.com/tour/kernel/unix/
                                                          8
V7の理解(2/2)
• V7ではハードが限定されていたため、可搬
  性について考慮していない
 – DECのPDP-11などで動作した
• 歴史についての参考資料
 http://ja.wikipedia.org/wiki/Version_7_Unix
• ソースコードは簡単シンプル、注釈が丁寧で
  読みやすいです…
 – ただしK&Rで書かれているっぽい

                                               9
user.h(1/5)
               冒頭の注釈
                                        (注釈のまんま)
 ↓左端の数値は行番号                             ・user構造体を定義している
                                        ・プロセスあたり1つ持つ
 1 /*                                   ・1プロセスあたりの全データであ
 2 * The user structure.                る
 3 * One allocated per process.         ・プロセスがスワップしている間は、
 4 * Contains all per process data      参照しなくてよい
                                        ・ユーザのブロック長はUSIZE×64
 5 * that doesn't need to be referenced
                                        でこれはスタックポインタ用に使わ
 6 * while the process is swapped.      れる
 7 * The user block is USIZE*64 bytes ・仮想カーネルのデータ長は
 8 * long; resides at virtual kernel    140000 (ユーザ毎のシステムス
 9 * loc 140000; contains the system    タック含む)
10 * stack per user; is cross referenced・同じプロセスの中では、proc構造
                                        と相互参照の関係にある
11   * with the proc structure for the
12   * same process.
13   */                                                10
14
15 #define EXCLOSE 01
                                                                  user.h(2/5)
 16
17 struct user
18 {
19            label_t u_rsav;                            /* save info when exchanging stacks */
20       int    u_fper;               /* FP error register */
                                                                             退避時にスタックポインタを格納
21       int    u_fpsaved;              /* FP regs saved for this proc */
22            struct {
23              int    u_fpsr;        /* FP status register */
24              double u_fpregs[6]; /* FP registers */                         ファイルI/O用の変数
25       } u_fps;
26       char u_segflg;                 /* IO flag: 0:user D; 1:system; 2:user I */ファイルI/Oの属性等
27       char u_error;                  /* return error code */                    Dはデータ、I、は命令
28       short u_uid;                  /* effective user id */                     systemはカーネルに相当
29       short u_gid;                  /* effective group id */
                                                                                   userはプロセスユーザと同義
30       short u_ruid;                 /* real user id */
31       short u_rgid;                 /* real group id */                              proc構造体ポインタ
32            struct proc *u_procp;                       /* pointer to proc structure */
33       int    *u_ap;                /* pointer to arglist */                 システムコールの引数リスト
34            union {                                     /* syscall return values */
35                       struct {
36                     int    r_val1;                               システムコールの戻り値
37                     int    r_val2;                               例えばLinuxのコマンド
38                       };                                         ls –laとかで得られる
39                       off_t      r_off;
                                                                    一覧のデータを格納
40                       time_t r_time;                                                           11
41       } u_r;                                                     しておく
user.h(3/5)
42       caddr_t u_base;                           /* base address for IO */
                                                                        プロセスユーザのI/Oの開始ア
43   unsigned int u_count;         /* bytes remaining for IO */
44       off_t       u_offset;
                                                                        ドレス、オフセット、どこのディ
                                                   /* offset in file for IO */
45       struct inode *u_cdir;                                          レクトリにあるか、パス名(この
                                                    /* pointer to inode of current directory */
46       struct inode *u_rdir;                                          ころは物理アドレス空間を直
                                                    /* root directory of current process */
47       char         u_dbuf[DIRSIZ];                                   接扱っていた?)
                                                    /* current pathname component */
48       caddr_t u_dirp;                           /* pathname pointer */
49       struct direct u_dent;                      /* current directory entry */
50       struct inode *u_pdir;                      /* inode of parent directory of dirp */
51   int     u_uisa[16];        /* prototype of segmentation addresses */
52   int     u_uisd[16];                                                ファイルI/O
                                /* prototype of segmentation descriptors */
53       struct file *u_ofile[NOFILE];              /* pointers to file structures of open files *
                                                                        (ちょっと詳細がわからない)
54       char         u_pofile[NOFILE];             /* per-process flags of open files */
55   int     u_arg[5];         /* arguments to current system call */
56   unsigned u_tsize;            /* text size (clicks) */
57   unsigned u_dsize;            /* data size (clicks) */              現在のシステムコール戻り値
58   unsigned u_ssize;            /* stack size (clicks) */
                                                                        テキスト(プログラム)、データ
59   label_t u_qsav;            /* label variable for quits and interrupts */
60   label_t u_ssav;            /* label variable for swapping */
                                                                        (固定値)、スタック(call時のP
61   int     u_signal[NSIG];     /* disposition of signals */           C値の格納等)のサイズ、ス
62   time_t u_utime;             /* this process user time */           ワップや退避時のラベル値
63   time_t u_stime;             /* this process system time */
64   time_t u_cutime;            /* sum of childs' utimes */            システムコールの戻り値
65   time_t u_cstime;            /* sum of childs' stimes */            プロセスおよび子プロセスの
66   int     *u_ar0;            /* address of users saved R0 */         CPU使用時間など         12
user.h(4/5)
75          struct tty *u_ttyp;                     /* controlling ttytty(キャラクタ端末)制御用ポイ
                                                                       pointer */
76          dev_t     u_ttyd;                      /* controlling tty ンタとデバイス制御用情報
                                                                      dev */
77          struct {                                /* header of executable file */
78            int    ux_mag;      /* magic number */
79            unsigned ux_tsize;   /* text size */
80            unsigned ux_dsize;    /* data size */                     これはわからない…
81            unsigned ux_bsize;    /* bss size */
82            unsigned ux_ssize;    /* symbol table size */
                                                                        実行するプログラムの
83            unsigned ux_entloc;   /* entry location */                情報(予備?)か何かか
84            unsigned ux_unused;
85            unsigned ux_relflg;
86      } u_exdata;
87          char       u_comm[DIRSIZ];
88          time_t u_start;
89      char u_acflag;
90      short u_fpflag;           /* unused now, will be later */    予備用(互換性を取るため?)
91      short u_cmask;             /* mask for file creation */
92      int    u_stack[1];
93                                       /* kernel stack per user
94                                        * extends from u + USIZE*64
95                                        * backward not to reach here
96                                        */
97 };
 98                                                                              13
user.h(5/5)
                          エラーコードの定義

101 /* u_error codes */       118 #define EEXIST 17
102 #define EPERM 1           119 #define EXDEV 18
103 #define ENOENT 2          120 #define ENODEV 19
104 #define ESRCH 3           121 #define ENOTDIR 20
105 #define EINTR 4           122 #define EISDIR 21
106 #define EIO   5           123 #define EINVAL 22
107 #define ENXIO 6           124 #define ENFILE 23
108 #define E2BIG 7           125 #define EMFILE 24
109 #define ENOEXEC 8         126 #define ENOTTY 25
110 #define EBADF 9           127 #define ETXTBSY 26
111 #define ECHILD 10         128 #define EFBIG 27
112 #define EAGAIN 11         129 #define ENOSPC 28
113 #define ENOMEM 12         130 #define ESPIPE 29
114 #define EACCES 13         131 #define EROFS 30
115 #define EFAULT 14         132 #define EMLINK 31
116 #define ENOTBLK 15        133 #define EPIPE 32
117 #define EBUSY 16          134 #define EDOM       33
                              135 #define ERANGE 34
                                                          14
slp.c
• プロセスのスケジューリングを行うための関数群
• 基本的にキューと、設定された優先度で管理するようだ
• 以下の関数について定義している(★は親関数っぽいもの)
 – sleep:プロセスの実行を中断し、プロセッサを明け渡す
 – wakeup:sleep中のプロセスを起こす
 – setrun:プロセスが実行できるようにする(スワップインできるようにす
   る)
 – setpri:プロセスユーザの優先度をセットする関数
 – ★sched:スケジューリング(スワッピング)のメイン関数
 – swapin:プロセスをスワップインさせる関数
 – qswitch:プロセスキューの設定を行う関数
 – ★switch:CPUのリスケジュール(資源の再割り当て)を行う場合に呼
   び出す
 – newproc:新しいプロセスを立ち上げる(fork?)
 – expand:データとスタックのサイズを変える
 – setrq:
                                      15
202 sched()
203 {
204           register struct proc *rp, *p;
                                                                        sched(1/3)
205           register outage, inage;                                ところどころに出てくる、
206
207
         int maxsize;                                                優先度を制御する関数。spl*の*が
208           /*                                                     大きいほど優先度が高く、6が最高。
209            * find user to swap in;
210            * of users ready, select one out longest
                                                                     他から割りこみが入って状態が
211            */                                                    変わらないようにしたい場合にこうする。
212
213 loop:                                                            ここでは最高優先度まで上げて以降の
214       spl6();                                                    操作を行っている
215       outage = -20000;
216           for (rp = &proc[0]; rp < &proc[NPROC]; rp++)
217           if (rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 &&         プロセスの状態を総なめして
218                rp->p_time - (rp->p_nice-NZERO)*8 > outage) {
219                    p = rp;                                         ステータスが実行可能状態で
220                    outage = rp->p_time - (rp->p_nice-NZERO)*8;     優先度が一番高いものを検出
221           }
222           /*                                                       (スワップイン候補を探す)
223             * If there is no one there, wait.
224             */
225      if (outage == -20000) {
226             runout++;                                      上記条件にあうプロセスが検出できなけれ
227                        sleep((caddr_t)&runout, PSWP);
228                goto loop;                                  ば、sleepを呼び出して待つ
229           }
230      spl0();
231
232           /*                                                     優先度を最低に戻す
233            * See if there is core for that process;
234            * if so, swap it in.
235            */
236
237           if (swapin(p))                                    プロセスに割り当てられる資源(メモリなど)
238                goto loop;                                   があればスワップインする     16
240        /*
                                                   sched(2/3)
241         * none found.
242         * look around for core.
243         * Select the largest of those sleeping
244         * at bad priority; if none, select the oldest.
245         */
246
247   spl6();
248        p = NULL;
249   maxsize = -1;
250   inage = -1;
251        for (rp = &proc[0]; rp < &proc[NPROC]; rp++) {
252                if (rp->p_stat==SZOMB
253                 || (rp->p_flag&(SSYS|SLOCK|SULOCK|SLOAD))!=SLOAD)
254                        continue;                                                   CPUに割り当
255                if (rp->p_textp && rp->p_textp->x_flag&XLOCK)
256                        continue;                                                   てる候補と資
257                if (rp->p_stat==SSLEEP&&rp->p_pri>=PZERO || rp->p_stat==SSTOP) {    源がない状
258                        if (maxsize < rp->p_size) {
259                                p = rp;                                             態。一番最初
260                                maxsize = rp->p_size;                               にsleepしたプ
261                        }
262                } else if (maxsize<0 && (rp->p_stat==SRUN||rp->p_stat==SSLEEP)) {   ロセスを総な
263                        if (rp->p_time+rp->p_nice-NZERO > inage) {                  めして検出す
264                                p = rp;
265                                inage = rp->p_time+rp->p_nice-NZERO;                る(優先的に
266
267                }
                           }
                                                                                       スワップさせ
268        }                                                                           るため)
269   spl0();
270        /*                                                                               17
sched(3/3)
270         /*
271          * Swap found user out if sleeping at bad pri,
272          * or if he has spent at least 2 seconds in core and
273          * the swapped-out process has spent at least 3 seconds out.
274          * Otherwise wait a bit and try again.
275          */
276         if (maxsize>=0 || (outage>=3 && inage>=2)) {
277                 p->p_flag &= ~SLOAD;
                                                             CPUに割り当てられた時間
278                 xswap(p, 1, 0);                          または、低い優先度でsleep
279             goto loop;
280         }
                                                             していたら、スワップを行う
281     spl6();                                              (理由がちょっと不明)
282     runin++;
283         sleep((caddr_t)&runin, PSWP);
284     goto loop;
285 }
286




                                                                                   18
347 swtch()
348 {
349
350
352
         register n;
              register struct proc *p, *q, *pp, *pq;
              /*
                                                                            switch(1/2)
353            * If not the idle process, resume the idle process.
354            */
355           if (u.u_procp != &proc[0]) {
356                   if (save(u.u_rsav)) {
357                    sureg();
358                               return;
359                      }                                                  スタックポインタか?を保存
360                      if (u.u_fpsaved==0) {                              や取り出している
361                              savfp(&u.u_fps);
362                              u.u_fpsaved = 1;
363                      }
364                      resume(proc[0].p_addr, u.u_qsav);
365           }
366      /*
367       * The first save returns nonzero when proc 0 is resumed
368       * by another process (above); then the second is not done
369       * and the process-search loop is entered.
370       *
371       * The first save returns 0 when swtch is called in proc 0
372       * from sched(). The second save returns 0 immediately, so
373       * in this case too the process-search loop is entered.
374       * Thus when proc 0 is awakened by being made runnable, it will
375       * find itself and resume itself at rsav, and return to sched().
376       */
377      if (save(u.u_qsav)==0 && save(u.u_rsav))
                                                                                            19
379 loop:
380       spl6();
381       runrun = 0;
382
383
384
               pp = NULL;
               q = NULL;
          n = 128;
                                                                                      switch(2/2)
385            /*
386              * Search for highest-priority runnable process
387              */
388            for(p=runq; p!=NULL; p=p->p_link) {
389                     if((p->p_stat==SRUN) && (p->p_flag&SLOAD)) {
390                             if(p->p_pri < n) {
391                                     pp = p;
392                                     pq = q;
393                                     n = p->p_pri;
394                             }
395                     }
396                     q = p;
397            }
398            /*
399              * If no process is runnable, idle.
400              */
401            p = pp;
402            if(p == NULL) {
403                 idle();
404                 goto loop;
405            }
406            q = pq;
407            if(q == NULL)
408                    runq = p->p_link;
409            else
410                    q->p_link = p->p_link;
411            curpri = n;
412       spl0();
413            /*
414             * The rsav (ssav) contents are interpreted in the new address space
415             */
416            n = p->p_flag&SSWAP;
417            p->p_flag &= ~SSWAP;
418            resume(p->p_addr, n? u.u_ssav: u.u_rsav);                                        20
419 }
292 swapin(p)
293 register struct proc *p;                                     swapin
294 {
295         register struct text *xp;
296     register int a;                                   ここ少し見たがまだ不明。
297     int x;
298
299          if ((a = malloc(coremap, p->p_size)) == NULL)
300                  return(0);
301          if (xp = p->p_textp) {
302                  xlock(xp);
303                  if (xp->x_ccount==0) {
304                          if ((x = malloc(coremap, xp->x_size)) == NULL) {
305                                  xunlock(xp);
306                                  mfree(coremap, p->p_size, a);
307                                  return(0);
308                          }
309                          xp->x_caddr = x;
310                          if ((xp->x_flag&XLOAD)==0)
311                                  swap(xp->x_daddr,x,xp->x_size,B_READ);
312                  }
313                  xp->x_ccount++;
314                  xunlock(xp);
315          }
316          swap(p->p_addr, a, p->p_size, B_READ);
317          mfree(swapmap, ctod(p->p_size), p->p_addr);
318          p->p_addr = a;
319          p->p_flag |= SLOAD;
320          p->p_time = 0;
321          return(1);                                                         21

More Related Content

What's hot

0章 Linuxカーネルを読む前に最低限知っておくべきこと
0章 Linuxカーネルを読む前に最低限知っておくべきこと0章 Linuxカーネルを読む前に最低限知っておくべきこと
0章 Linuxカーネルを読む前に最低限知っておくべきことmao999
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門sandai
 
cdev_write and_comwrite
cdev_write and_comwritecdev_write and_comwrite
cdev_write and_comwritekusabanachi
 
詳解Dexファイルフォーマット
詳解Dexファイルフォーマット詳解Dexファイルフォーマット
詳解DexファイルフォーマットTakuya Matsunaga
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルkusabanachi
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門sandai
 
dofilewrite and vn_write
dofilewrite and vn_writedofilewrite and vn_write
dofilewrite and vn_writekusabanachi
 
CLRの基礎 - プログラミング .NET Framework 第3版 読書会
CLRの基礎 - プログラミング .NET Framework 第3版 読書会CLRの基礎 - プログラミング .NET Framework 第3版 読書会
CLRの基礎 - プログラミング .NET Framework 第3版 読書会Yoshihisa Ozaki
 
x86-64/Linuxに独自メモリ空間を勝手増設
x86-64/Linuxに独自メモリ空間を勝手増設x86-64/Linuxに独自メモリ空間を勝手増設
x86-64/Linuxに独自メモリ空間を勝手増設Minoru Nakamura
 
Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Norito Agetsuma
 
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdmod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdTaisuke Yamada
 
【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門 【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門 sandai
 
C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介yohhoy
 
Pythonista も ls を読むべきか?
Pythonista も ls を読むべきか?Pythonista も ls を読むべきか?
Pythonista も ls を読むべきか?Katsunori FUJIWARA
 
HDFSネームノードのHAについて #hcj13w
HDFSネームノードのHAについて #hcj13wHDFSネームノードのHAについて #hcj13w
HDFSネームノードのHAについて #hcj13wCloudera Japan
 
仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプト仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプトbsdhack
 
本当にわかる Spectre と Meltdown
本当にわかる Spectre と Meltdown本当にわかる Spectre と Meltdown
本当にわかる Spectre と MeltdownHirotaka Kawata
 

What's hot (20)

0章 Linuxカーネルを読む前に最低限知っておくべきこと
0章 Linuxカーネルを読む前に最低限知っておくべきこと0章 Linuxカーネルを読む前に最低限知っておくべきこと
0章 Linuxカーネルを読む前に最低限知っておくべきこと
 
【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門【学習メモ#5th】12ステップで作る組込みOS自作入門
【学習メモ#5th】12ステップで作る組込みOS自作入門
 
cdev_write and_comwrite
cdev_write and_comwritecdev_write and_comwrite
cdev_write and_comwrite
 
詳解Dexファイルフォーマット
詳解Dexファイルフォーマット詳解Dexファイルフォーマット
詳解Dexファイルフォーマット
 
NetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブルNetBSD/i386 割り込みベクタテーブル
NetBSD/i386 割り込みベクタテーブル
 
【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門【学習メモ#3rd】12ステップで作る組込みOS自作入門
【学習メモ#3rd】12ステップで作る組込みOS自作入門
 
V6 unix in okinawa
V6 unix in okinawaV6 unix in okinawa
V6 unix in okinawa
 
dofilewrite and vn_write
dofilewrite and vn_writedofilewrite and vn_write
dofilewrite and vn_write
 
CLRの基礎 - プログラミング .NET Framework 第3版 読書会
CLRの基礎 - プログラミング .NET Framework 第3版 読書会CLRの基礎 - プログラミング .NET Framework 第3版 読書会
CLRの基礎 - プログラミング .NET Framework 第3版 読書会
 
x86-64/Linuxに独自メモリ空間を勝手増設
x86-64/Linuxに独自メモリ空間を勝手増設x86-64/Linuxに独自メモリ空間を勝手増設
x86-64/Linuxに独自メモリ空間を勝手増設
 
d-kami x86-2
d-kami x86-2d-kami x86-2
d-kami x86-2
 
Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御
 
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpdmod_auth_ticket - Bringing Single-Sign-On to lighttpd
mod_auth_ticket - Bringing Single-Sign-On to lighttpd
 
【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門 【学習メモ#7th】12ステップで作る組込みOS自作入門
【学習メモ#7th】12ステップで作る組込みOS自作入門
 
C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介C++ Transactional Memory言語拡張の紹介
C++ Transactional Memory言語拡張の紹介
 
Memory sanitizer
Memory sanitizerMemory sanitizer
Memory sanitizer
 
Pythonista も ls を読むべきか?
Pythonista も ls を読むべきか?Pythonista も ls を読むべきか?
Pythonista も ls を読むべきか?
 
HDFSネームノードのHAについて #hcj13w
HDFSネームノードのHAについて #hcj13wHDFSネームノードのHAについて #hcj13w
HDFSネームノードのHAについて #hcj13w
 
仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプト仕事で使えるシェルスクリプト
仕事で使えるシェルスクリプト
 
本当にわかる Spectre と Meltdown
本当にわかる Spectre と Meltdown本当にわかる Spectre と Meltdown
本当にわかる Spectre と Meltdown
 

Viewers also liked

Save Mziuri
Save MziuriSave Mziuri
Save Mziuriuelab
 
Klonopin dangers
Klonopin dangersKlonopin dangers
Klonopin dangersBdeen Rud
 
Klonopin and ativan
Klonopin and ativanKlonopin and ativan
Klonopin and ativanBdeen Rud
 
6 mg klonopin
6 mg klonopin6 mg klonopin
6 mg klonopinBdeen Rud
 
Klonopin euphoria
Klonopin euphoriaKlonopin euphoria
Klonopin euphoriaBdeen Rud
 
An Aggressive Strain of Pucciniastriiformis:Discovery and Documentation
An Aggressive Strain of Pucciniastriiformis:Discovery and DocumentationAn Aggressive Strain of Pucciniastriiformis:Discovery and Documentation
An Aggressive Strain of Pucciniastriiformis:Discovery and DocumentationBorlaug Global Rust Initiative
 
ฐานข้อมูล
ฐานข้อมูลฐานข้อมูล
ฐานข้อมูลChemist Atom
 
Peter Smith: Allocating health care budgets to general practices
Peter Smith: Allocating health care budgets to general practicesPeter Smith: Allocating health care budgets to general practices
Peter Smith: Allocating health care budgets to general practicesNuffield Trust
 
323- Bras dessus bras dessous
323- Bras dessus bras dessous323- Bras dessus bras dessous
323- Bras dessus bras dessousmireille 30100
 
logo-flowers-ae-2016-black-bg
logo-flowers-ae-2016-black-bglogo-flowers-ae-2016-black-bg
logo-flowers-ae-2016-black-bgMartin O'Gara
 
Money is my_friend_cz.5
Money is my_friend_cz.5Money is my_friend_cz.5
Money is my_friend_cz.5Teresa Nowicka
 
Health and med tech opportunities
Health and med tech opportunitiesHealth and med tech opportunities
Health and med tech opportunitieseventsbbaa
 

Viewers also liked (20)

Rh3
Rh3Rh3
Rh3
 
Skolotāja Valentīna Nagle
Skolotāja Valentīna NagleSkolotāja Valentīna Nagle
Skolotāja Valentīna Nagle
 
317- Huskies
317- Huskies317- Huskies
317- Huskies
 
Save Mziuri
Save MziuriSave Mziuri
Save Mziuri
 
Klonopin dangers
Klonopin dangersKlonopin dangers
Klonopin dangers
 
Rkk9
Rkk9Rkk9
Rkk9
 
Klonopin and ativan
Klonopin and ativanKlonopin and ativan
Klonopin and ativan
 
6 mg klonopin
6 mg klonopin6 mg klonopin
6 mg klonopin
 
Klonopin euphoria
Klonopin euphoriaKlonopin euphoria
Klonopin euphoria
 
An Aggressive Strain of Pucciniastriiformis:Discovery and Documentation
An Aggressive Strain of Pucciniastriiformis:Discovery and DocumentationAn Aggressive Strain of Pucciniastriiformis:Discovery and Documentation
An Aggressive Strain of Pucciniastriiformis:Discovery and Documentation
 
Kref.net'te firmalar
Kref.net'te firmalarKref.net'te firmalar
Kref.net'te firmalar
 
ฐานข้อมูล
ฐานข้อมูลฐานข้อมูล
ฐานข้อมูล
 
La feria de la ciencia y la tecnología
La feria de la ciencia y la tecnologíaLa feria de la ciencia y la tecnología
La feria de la ciencia y la tecnología
 
Mlsp bpc
Mlsp bpcMlsp bpc
Mlsp bpc
 
Peter Smith: Allocating health care budgets to general practices
Peter Smith: Allocating health care budgets to general practicesPeter Smith: Allocating health care budgets to general practices
Peter Smith: Allocating health care budgets to general practices
 
323- Bras dessus bras dessous
323- Bras dessus bras dessous323- Bras dessus bras dessous
323- Bras dessus bras dessous
 
logo-flowers-ae-2016-black-bg
logo-flowers-ae-2016-black-bglogo-flowers-ae-2016-black-bg
logo-flowers-ae-2016-black-bg
 
Money is my_friend_cz.5
Money is my_friend_cz.5Money is my_friend_cz.5
Money is my_friend_cz.5
 
Tugas perencanaan
Tugas perencanaanTugas perencanaan
Tugas perencanaan
 
Health and med tech opportunities
Health and med tech opportunitiesHealth and med tech opportunities
Health and med tech opportunities
 

Similar to 2011.06.11 v7から始めるunix まとめ

○○大学の本当にあった怖い話
○○大学の本当にあった怖い話○○大学の本当にあった怖い話
○○大学の本当にあった怖い話idkqh7 Nishino
 
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)inaz2
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPNSaitoNmiri
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0Kiwamu Okabe
 
Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etckasaharatt
 
Functions
FunctionsFunctions
Functionsdo_aki
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Takuya Matsunaga
 
4章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 54章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 5mao999
 
Unix 基礎
Unix 基礎Unix 基礎
Unix 基礎Sho A
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。Satoshi Mimura
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 sandai
 
nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8yohhoy
 
Rubyで創るOpenFlowネットワーク - LLまつり
Rubyで創るOpenFlowネットワーク - LLまつりRubyで創るOpenFlowネットワーク - LLまつり
Rubyで創るOpenFlowネットワーク - LLまつりYuya Rin
 
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)洋史 東平
 

Similar to 2011.06.11 v7から始めるunix まとめ (20)

Ext4 filesystem(1)
Ext4 filesystem(1)Ext4 filesystem(1)
Ext4 filesystem(1)
 
○○大学の本当にあった怖い話
○○大学の本当にあった怖い話○○大学の本当にあった怖い話
○○大学の本当にあった怖い話
 
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
ROP Illmatic: Exploring Universal ROP on glibc x86-64 (ja)
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSP
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etc
 
0622
06220622
0622
 
initramfsについて
initramfsについてinitramfsについて
initramfsについて
 
Functions
FunctionsFunctions
Functions
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
 
4章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 54章 Linuxカーネル - 割り込み・例外 5
4章 Linuxカーネル - 割り込み・例外 5
 
Unix 基礎
Unix 基礎Unix 基礎
Unix 基礎
 
Linux Namespace
Linux NamespaceLinux Namespace
Linux Namespace
 
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
APASEC 2013 - ROP/JIT を使わずに DEP/ASLR を回避する手法を見てみた。
 
【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門 【学習メモ#8th】12ステップで作る組込みOS自作入門
【学習メモ#8th】12ステップで作る組込みOS自作入門
 
nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8nakameguro_feature.cpp vol.8
nakameguro_feature.cpp vol.8
 
Linux Namespaces
Linux NamespacesLinux Namespaces
Linux Namespaces
 
Rubyで創るOpenFlowネットワーク - LLまつり
Rubyで創るOpenFlowネットワーク - LLまつりRubyで創るOpenFlowネットワーク - LLまつり
Rubyで創るOpenFlowネットワーク - LLまつり
 
01 php7
01   php701   php7
01 php7
 
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)
clu2cは64ビットOSでも使えます (OSC 2012 Hiroshima LT用資料)
 

More from Makiko Konoshima

食事写真集[中華料理]
食事写真集[中華料理]食事写真集[中華料理]
食事写真集[中華料理]Makiko Konoshima
 
食事写真集[ムール貝]
食事写真集[ムール貝]食事写真集[ムール貝]
食事写真集[ムール貝]Makiko Konoshima
 
食事写真集[エーデルワイス]
食事写真集[エーデルワイス]食事写真集[エーデルワイス]
食事写真集[エーデルワイス]Makiko Konoshima
 
食事写真集[フランス料理]
食事写真集[フランス料理]食事写真集[フランス料理]
食事写真集[フランス料理]Makiko Konoshima
 
2011.06.03 v7から始めるunix まとめ
2011.06.03 v7から始めるunix まとめ2011.06.03 v7から始めるunix まとめ
2011.06.03 v7から始めるunix まとめMakiko Konoshima
 

More from Makiko Konoshima (6)

原稿4
原稿4原稿4
原稿4
 
食事写真集[中華料理]
食事写真集[中華料理]食事写真集[中華料理]
食事写真集[中華料理]
 
食事写真集[ムール貝]
食事写真集[ムール貝]食事写真集[ムール貝]
食事写真集[ムール貝]
 
食事写真集[エーデルワイス]
食事写真集[エーデルワイス]食事写真集[エーデルワイス]
食事写真集[エーデルワイス]
 
食事写真集[フランス料理]
食事写真集[フランス料理]食事写真集[フランス料理]
食事写真集[フランス料理]
 
2011.06.03 v7から始めるunix まとめ
2011.06.03 v7から始めるunix まとめ2011.06.03 v7から始めるunix まとめ
2011.06.03 v7から始めるunix まとめ
 

Recently uploaded

東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2Tokyo Institute of Technology
 
UniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptUniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptyuitoakatsukijp
 
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ssusere0a682
 
The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024koheioishi1
 
TEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfTEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfyukisuga3
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationYukiTerazawa
 

Recently uploaded (6)

東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
 
UniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScriptUniProject Workshop Make a Discord Bot with JavaScript
UniProject Workshop Make a Discord Bot with JavaScript
 
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習105 -n人囚人のジレンマモデル- #ゲーム理論 #gametheory #数学
 
The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
 
TEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdfTEAMIN Service overview for customer_20240422.pdf
TEAMIN Service overview for customer_20240422.pdf
 
TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
 

2011.06.11 v7から始めるunix まとめ

  • 1. V7から始めるUNIX まとめ 予備知識であるCPUアーキテクチャのほん のさわりを説明したあと、本題に入ります
  • 2. 予備知識 • コンピュータ・アーキテクチャについて – 低レイヤのプログラムの理解に欠かせない – 理想を言えば、網羅的に知っておくことが好ましい • ハードとソフトは両輪だから – ただし、技術の範囲が広大すぎて、とてもここでは扱いき れない – 疑問が出た都度、身近な専門家に声をかけて聞くと、きっ と親切に教えてくれる!←学校か職場の専門家が誰か、 把握しておこう! • 私も知っている範囲で答えます – ここではCPUの基本構成、マシン語から演算器で実行さ れる手順にフォーカスして、次ページ以降で少しだけさわ る 2
  • 3. CPUの基本構成、超ざっくり • 参考情報※の本文が、非 常に素晴らしいので、そち らに詳細の解説はゆずり ます – CPUは大きく、演算部と制 御部から構成されます – CPUにはメモリが接続され ています – ROMには、コンパイラに よってプログラムから変換 され、CPUが実行可能な マシン語に変換されたデー タが入っています ※参考:http://homepage2.nifty.com/ttoyoshima/Computer/Config.htm 3
  • 4. マシン語 • プログラム言語はコンパイラによってCPUが直接理 解し実行できるマシン語に変換される • マシン語は、CPUで処理される(命令パイプライン) • マシン語の例 参考情報 http://www.geocities.jp/mori_imms/asmDetail.html http://msyk.net/keio/JavaBook/ch1.html 4
  • 5. 命令パイプライン(1/2) • 汎用パイプラインについて説明する • 次ページの図は、一般化した次のような4段のパイプライン を示している。 • フェッチ (Fetch):メモリから機械語を取り出してくる動作 • デコード (Decode):機械語を解読し、制御信号を送る • 実行 (Execute):実行する • ライトバック (Write-back):実行結果をファイルかメモリに書き 込む • 次ページの図の上にある灰色の矩形には実行を待っている 命令が並んでいる。下の灰色の矩形には実行が完了した命 令が並んでいる。真ん中の矩形がパイプラインを表している。 • 実行は次ページのようになる。 参考:Wikipedia 5
  • 6. 命令パイプライン(2/2) 説明 0 4つの命令が実行されるのを待っている。 1 緑の命令をメモリからフェッチする。 緑の命令をデコードする。 2 紫の命令をメモリからフェッチする。 緑の命令を実行する(実際の命令処理を行う) 3 紫の命令をデコードする。 青の命令をフェッチする。 緑の命令の結果をレジスタファイルかメモリに書き込む 紫の命令を実行する。 4 青の命令をデコードする。 赤の命令をフェッチする。 緑の命令は完了した。 紫の命令の結果を書き込む。 5 青の命令を実行する。 赤の命令をデコードする。 紫の命令は完了した。 6 青の命令の結果を書き込む。 赤の命令を実行する。 青の命令は完了した。 7 赤の命令の結果を書き込む。 8 赤の命令は完了した。 9 全命令を実行した。 6
  • 7. • 示した例は、一般的な例です • 実際はもっと複雑で、いろいろ工夫されてい ます • 気に入っている、または気になるチップの アーキテクチャを調べていくと、楽しいです – チップメーカーは大抵、開発者向けのホワイト ペーパーを出しています – わからない専門用語は、専門家に聞こう! • 私も知っている範囲で答えます 7
  • 8. V7の理解(1/2) • 現在のLinuxの原点はV7 – V7→BSD→Linux • V7を読み解くことで、原理の理解を進めることを 目的とする • 今回は、V7の理解の一環として、まず root/h/user.hとroot/sys/slp.cの実装を読み解い ていく – slp.cはスワッピングについて記載されており、プロセ ス制御の基本です • 若干「わかっているつもり」な人向け 参照したソースコード: http://www.tamacom.com/tour/kernel/unix/ 8
  • 9. V7の理解(2/2) • V7ではハードが限定されていたため、可搬 性について考慮していない – DECのPDP-11などで動作した • 歴史についての参考資料 http://ja.wikipedia.org/wiki/Version_7_Unix • ソースコードは簡単シンプル、注釈が丁寧で 読みやすいです… – ただしK&Rで書かれているっぽい 9
  • 10. user.h(1/5) 冒頭の注釈 (注釈のまんま) ↓左端の数値は行番号 ・user構造体を定義している ・プロセスあたり1つ持つ 1 /* ・1プロセスあたりの全データであ 2 * The user structure. る 3 * One allocated per process. ・プロセスがスワップしている間は、 4 * Contains all per process data 参照しなくてよい ・ユーザのブロック長はUSIZE×64 5 * that doesn't need to be referenced でこれはスタックポインタ用に使わ 6 * while the process is swapped. れる 7 * The user block is USIZE*64 bytes ・仮想カーネルのデータ長は 8 * long; resides at virtual kernel 140000 (ユーザ毎のシステムス 9 * loc 140000; contains the system タック含む) 10 * stack per user; is cross referenced・同じプロセスの中では、proc構造 と相互参照の関係にある 11 * with the proc structure for the 12 * same process. 13 */ 10
  • 11. 14 15 #define EXCLOSE 01 user.h(2/5) 16 17 struct user 18 { 19 label_t u_rsav; /* save info when exchanging stacks */ 20 int u_fper; /* FP error register */ 退避時にスタックポインタを格納 21 int u_fpsaved; /* FP regs saved for this proc */ 22 struct { 23 int u_fpsr; /* FP status register */ 24 double u_fpregs[6]; /* FP registers */ ファイルI/O用の変数 25 } u_fps; 26 char u_segflg; /* IO flag: 0:user D; 1:system; 2:user I */ファイルI/Oの属性等 27 char u_error; /* return error code */ Dはデータ、I、は命令 28 short u_uid; /* effective user id */ systemはカーネルに相当 29 short u_gid; /* effective group id */ userはプロセスユーザと同義 30 short u_ruid; /* real user id */ 31 short u_rgid; /* real group id */ proc構造体ポインタ 32 struct proc *u_procp; /* pointer to proc structure */ 33 int *u_ap; /* pointer to arglist */ システムコールの引数リスト 34 union { /* syscall return values */ 35 struct { 36 int r_val1; システムコールの戻り値 37 int r_val2; 例えばLinuxのコマンド 38 }; ls –laとかで得られる 39 off_t r_off; 一覧のデータを格納 40 time_t r_time; 11 41 } u_r; しておく
  • 12. user.h(3/5) 42 caddr_t u_base; /* base address for IO */ プロセスユーザのI/Oの開始ア 43 unsigned int u_count; /* bytes remaining for IO */ 44 off_t u_offset; ドレス、オフセット、どこのディ /* offset in file for IO */ 45 struct inode *u_cdir; レクトリにあるか、パス名(この /* pointer to inode of current directory */ 46 struct inode *u_rdir; ころは物理アドレス空間を直 /* root directory of current process */ 47 char u_dbuf[DIRSIZ]; 接扱っていた?) /* current pathname component */ 48 caddr_t u_dirp; /* pathname pointer */ 49 struct direct u_dent; /* current directory entry */ 50 struct inode *u_pdir; /* inode of parent directory of dirp */ 51 int u_uisa[16]; /* prototype of segmentation addresses */ 52 int u_uisd[16]; ファイルI/O /* prototype of segmentation descriptors */ 53 struct file *u_ofile[NOFILE]; /* pointers to file structures of open files * (ちょっと詳細がわからない) 54 char u_pofile[NOFILE]; /* per-process flags of open files */ 55 int u_arg[5]; /* arguments to current system call */ 56 unsigned u_tsize; /* text size (clicks) */ 57 unsigned u_dsize; /* data size (clicks) */ 現在のシステムコール戻り値 58 unsigned u_ssize; /* stack size (clicks) */ テキスト(プログラム)、データ 59 label_t u_qsav; /* label variable for quits and interrupts */ 60 label_t u_ssav; /* label variable for swapping */ (固定値)、スタック(call時のP 61 int u_signal[NSIG]; /* disposition of signals */ C値の格納等)のサイズ、ス 62 time_t u_utime; /* this process user time */ ワップや退避時のラベル値 63 time_t u_stime; /* this process system time */ 64 time_t u_cutime; /* sum of childs' utimes */ システムコールの戻り値 65 time_t u_cstime; /* sum of childs' stimes */ プロセスおよび子プロセスの 66 int *u_ar0; /* address of users saved R0 */ CPU使用時間など 12
  • 13. user.h(4/5) 75 struct tty *u_ttyp; /* controlling ttytty(キャラクタ端末)制御用ポイ pointer */ 76 dev_t u_ttyd; /* controlling tty ンタとデバイス制御用情報 dev */ 77 struct { /* header of executable file */ 78 int ux_mag; /* magic number */ 79 unsigned ux_tsize; /* text size */ 80 unsigned ux_dsize; /* data size */ これはわからない… 81 unsigned ux_bsize; /* bss size */ 82 unsigned ux_ssize; /* symbol table size */ 実行するプログラムの 83 unsigned ux_entloc; /* entry location */ 情報(予備?)か何かか 84 unsigned ux_unused; 85 unsigned ux_relflg; 86 } u_exdata; 87 char u_comm[DIRSIZ]; 88 time_t u_start; 89 char u_acflag; 90 short u_fpflag; /* unused now, will be later */ 予備用(互換性を取るため?) 91 short u_cmask; /* mask for file creation */ 92 int u_stack[1]; 93 /* kernel stack per user 94 * extends from u + USIZE*64 95 * backward not to reach here 96 */ 97 }; 98 13
  • 14. user.h(5/5) エラーコードの定義 101 /* u_error codes */ 118 #define EEXIST 17 102 #define EPERM 1 119 #define EXDEV 18 103 #define ENOENT 2 120 #define ENODEV 19 104 #define ESRCH 3 121 #define ENOTDIR 20 105 #define EINTR 4 122 #define EISDIR 21 106 #define EIO 5 123 #define EINVAL 22 107 #define ENXIO 6 124 #define ENFILE 23 108 #define E2BIG 7 125 #define EMFILE 24 109 #define ENOEXEC 8 126 #define ENOTTY 25 110 #define EBADF 9 127 #define ETXTBSY 26 111 #define ECHILD 10 128 #define EFBIG 27 112 #define EAGAIN 11 129 #define ENOSPC 28 113 #define ENOMEM 12 130 #define ESPIPE 29 114 #define EACCES 13 131 #define EROFS 30 115 #define EFAULT 14 132 #define EMLINK 31 116 #define ENOTBLK 15 133 #define EPIPE 32 117 #define EBUSY 16 134 #define EDOM 33 135 #define ERANGE 34 14
  • 15. slp.c • プロセスのスケジューリングを行うための関数群 • 基本的にキューと、設定された優先度で管理するようだ • 以下の関数について定義している(★は親関数っぽいもの) – sleep:プロセスの実行を中断し、プロセッサを明け渡す – wakeup:sleep中のプロセスを起こす – setrun:プロセスが実行できるようにする(スワップインできるようにす る) – setpri:プロセスユーザの優先度をセットする関数 – ★sched:スケジューリング(スワッピング)のメイン関数 – swapin:プロセスをスワップインさせる関数 – qswitch:プロセスキューの設定を行う関数 – ★switch:CPUのリスケジュール(資源の再割り当て)を行う場合に呼 び出す – newproc:新しいプロセスを立ち上げる(fork?) – expand:データとスタックのサイズを変える – setrq: 15
  • 16. 202 sched() 203 { 204 register struct proc *rp, *p; sched(1/3) 205 register outage, inage; ところどころに出てくる、 206 207 int maxsize; 優先度を制御する関数。spl*の*が 208 /* 大きいほど優先度が高く、6が最高。 209 * find user to swap in; 210 * of users ready, select one out longest 他から割りこみが入って状態が 211 */ 変わらないようにしたい場合にこうする。 212 213 loop: ここでは最高優先度まで上げて以降の 214 spl6(); 操作を行っている 215 outage = -20000; 216 for (rp = &proc[0]; rp < &proc[NPROC]; rp++) 217 if (rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && プロセスの状態を総なめして 218 rp->p_time - (rp->p_nice-NZERO)*8 > outage) { 219 p = rp; ステータスが実行可能状態で 220 outage = rp->p_time - (rp->p_nice-NZERO)*8; 優先度が一番高いものを検出 221 } 222 /* (スワップイン候補を探す) 223 * If there is no one there, wait. 224 */ 225 if (outage == -20000) { 226 runout++; 上記条件にあうプロセスが検出できなけれ 227 sleep((caddr_t)&runout, PSWP); 228 goto loop; ば、sleepを呼び出して待つ 229 } 230 spl0(); 231 232 /* 優先度を最低に戻す 233 * See if there is core for that process; 234 * if so, swap it in. 235 */ 236 237 if (swapin(p)) プロセスに割り当てられる資源(メモリなど) 238 goto loop; があればスワップインする 16
  • 17. 240 /* sched(2/3) 241 * none found. 242 * look around for core. 243 * Select the largest of those sleeping 244 * at bad priority; if none, select the oldest. 245 */ 246 247 spl6(); 248 p = NULL; 249 maxsize = -1; 250 inage = -1; 251 for (rp = &proc[0]; rp < &proc[NPROC]; rp++) { 252 if (rp->p_stat==SZOMB 253 || (rp->p_flag&(SSYS|SLOCK|SULOCK|SLOAD))!=SLOAD) 254 continue; CPUに割り当 255 if (rp->p_textp && rp->p_textp->x_flag&XLOCK) 256 continue; てる候補と資 257 if (rp->p_stat==SSLEEP&&rp->p_pri>=PZERO || rp->p_stat==SSTOP) { 源がない状 258 if (maxsize < rp->p_size) { 259 p = rp; 態。一番最初 260 maxsize = rp->p_size; にsleepしたプ 261 } 262 } else if (maxsize<0 && (rp->p_stat==SRUN||rp->p_stat==SSLEEP)) { ロセスを総な 263 if (rp->p_time+rp->p_nice-NZERO > inage) { めして検出す 264 p = rp; 265 inage = rp->p_time+rp->p_nice-NZERO; る(優先的に 266 267 } } スワップさせ 268 } るため) 269 spl0(); 270 /* 17
  • 18. sched(3/3) 270 /* 271 * Swap found user out if sleeping at bad pri, 272 * or if he has spent at least 2 seconds in core and 273 * the swapped-out process has spent at least 3 seconds out. 274 * Otherwise wait a bit and try again. 275 */ 276 if (maxsize>=0 || (outage>=3 && inage>=2)) { 277 p->p_flag &= ~SLOAD; CPUに割り当てられた時間 278 xswap(p, 1, 0); または、低い優先度でsleep 279 goto loop; 280 } していたら、スワップを行う 281 spl6(); (理由がちょっと不明) 282 runin++; 283 sleep((caddr_t)&runin, PSWP); 284 goto loop; 285 } 286 18
  • 19. 347 swtch() 348 { 349 350 352 register n; register struct proc *p, *q, *pp, *pq; /* switch(1/2) 353 * If not the idle process, resume the idle process. 354 */ 355 if (u.u_procp != &proc[0]) { 356 if (save(u.u_rsav)) { 357 sureg(); 358 return; 359 } スタックポインタか?を保存 360 if (u.u_fpsaved==0) { や取り出している 361 savfp(&u.u_fps); 362 u.u_fpsaved = 1; 363 } 364 resume(proc[0].p_addr, u.u_qsav); 365 } 366 /* 367 * The first save returns nonzero when proc 0 is resumed 368 * by another process (above); then the second is not done 369 * and the process-search loop is entered. 370 * 371 * The first save returns 0 when swtch is called in proc 0 372 * from sched(). The second save returns 0 immediately, so 373 * in this case too the process-search loop is entered. 374 * Thus when proc 0 is awakened by being made runnable, it will 375 * find itself and resume itself at rsav, and return to sched(). 376 */ 377 if (save(u.u_qsav)==0 && save(u.u_rsav)) 19
  • 20. 379 loop: 380 spl6(); 381 runrun = 0; 382 383 384 pp = NULL; q = NULL; n = 128; switch(2/2) 385 /* 386 * Search for highest-priority runnable process 387 */ 388 for(p=runq; p!=NULL; p=p->p_link) { 389 if((p->p_stat==SRUN) && (p->p_flag&SLOAD)) { 390 if(p->p_pri < n) { 391 pp = p; 392 pq = q; 393 n = p->p_pri; 394 } 395 } 396 q = p; 397 } 398 /* 399 * If no process is runnable, idle. 400 */ 401 p = pp; 402 if(p == NULL) { 403 idle(); 404 goto loop; 405 } 406 q = pq; 407 if(q == NULL) 408 runq = p->p_link; 409 else 410 q->p_link = p->p_link; 411 curpri = n; 412 spl0(); 413 /* 414 * The rsav (ssav) contents are interpreted in the new address space 415 */ 416 n = p->p_flag&SSWAP; 417 p->p_flag &= ~SSWAP; 418 resume(p->p_addr, n? u.u_ssav: u.u_rsav); 20 419 }
  • 21. 292 swapin(p) 293 register struct proc *p; swapin 294 { 295 register struct text *xp; 296 register int a; ここ少し見たがまだ不明。 297 int x; 298 299 if ((a = malloc(coremap, p->p_size)) == NULL) 300 return(0); 301 if (xp = p->p_textp) { 302 xlock(xp); 303 if (xp->x_ccount==0) { 304 if ((x = malloc(coremap, xp->x_size)) == NULL) { 305 xunlock(xp); 306 mfree(coremap, p->p_size, a); 307 return(0); 308 } 309 xp->x_caddr = x; 310 if ((xp->x_flag&XLOAD)==0) 311 swap(xp->x_daddr,x,xp->x_size,B_READ); 312 } 313 xp->x_ccount++; 314 xunlock(xp); 315 } 316 swap(p->p_addr, a, p->p_size, B_READ); 317 mfree(swapmap, ctod(p->p_size), p->p_addr); 318 p->p_addr = a; 319 p->p_flag |= SLOAD; 320 p->p_time = 0; 321 return(1); 21