SlideShare a Scribd company logo
xv6のコンテキストスイッチを読む

              @mfumi2
自己紹介

●
    セキュリティキャンプ2012OS組
最近こんな本が出ました




              はじめてのOSコードリーディング
                         青柳隆宏著




              おすすめ! でも...
UNIX V6 を読む上で大変なところ

●
    PDP11
●
    Cの記法が古い (pre K&R)
●
    アセンブラの記法が特殊
●
    デフォルトが8進数
●
    etc...
xv6とは

●
    MITで開発された教育用OS
    http://pdos.csail.mit.edu/6.828/2012/xv6.html
●
    UNIX V6 を x86 向けに書き直したもの
●
    解説書有り
    http://pdos.csail.mit.edu/6.828/2012/xv6/book-
    rev7.pdf
xv6の特徴

●
    x86
●
    マルチプロセッサ対応
●
    バイナリはELF
●
    スワッピング機能はなし
●
    qemu+gdb で動作可
コンテキストスイッチ

●
    プロセスのコンテキストを切り替える
●
    コンテキスト …
    –   メモリ空間
        → cr3 レジスタを切り替える
    –   スタック
        → %esp を切り替える
    –   各種レジスタ
        → プロセスごとのスタックに退避&スタックから復帰
xv6のコンテキストスイッチ
• switch.S


             void swtch(struct context **old,
                                    struct context *new);




                       • proc.h
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ
                     %
                     %
                     %
★
                     %                              %esp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ
                     %edi
                     %esi
                     %ebx                           %esp
★
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ
                     %edi
                     %esi                           %esp
                     %ebx
★
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ
                     %edi                           %esp
                     %esi
                     %ebx
                     %ebp
★                    %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                    %esp
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
★


                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                    %esp
                     %edi                           *old(%eax)
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)



★                                                  new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                   *old(%eax)
                      %edi
                      %esi
                      %ebx
                      %ebp
                      %eip(swtchの戻り先)


                                                    %esp
                                                    new(%edx)
★                     %edi
                      %esi
                      %ebx
                      %ebp
                      %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                   *old(%eax)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi                          %esp
                     %esi
                     %ebx
★                    %ebp
                     %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                   *old(%eax)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi                           %esp
                     %ebx
                     %ebp
★                    %eip(swtchの戻り先)
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                   *old(%eax)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx                           %esp
                     %ebp
                     %eip(swtchの戻り先)
★
xv6のコンテキストスイッチ
    • switch.S
                 void swtch(struct context **old,
                                        struct context *new);
                             メモリ                   *old(%eax)
                     %edi
                     %esi
                     %ebx
                     %ebp
                     %eip(swtchの戻り先)



                                                   new(%edx)
                     %edi
                     %esi
                     %ebx
                     %ebp                           %esp
                     %eip(swtchの戻り先)
★
xv6のコンテキストスイッチの流れ


ユーザプロセス1                                ユーザプロセス2

    タイマ割り込み                                 iret
                
割り込みハンドラ             スケジューラ             割り込みハンドラ
           swtch()            swtch()
(1) 割り込みの発生

●
    xv6では100msごとにタイマ割り込みが発生
●
    割り込みが発生すると
    –   特権レベルが3から0に移行
    –   スタックがカーネルスタックに切り替わる
        (TSSからカーネル用%espと%ssを読み込む)
    –   スタックに%ss, %esp, %eflags, %cs, %eip を積む
        (現在実行していたプロセスの状態を積む)
    –   対応する割り込みハンドラに移行
(1) 割り込みの発生

    xv6では
●
    vectors.S (vectors.plから生成される) 内に定義してあ
    る vector$i() ($iは割り込み番号) が呼び出される
    (割り込みハンドラの設定は trap.c の tvinit(), idtinit(), いずれも main.c
    のmain()から呼ばれる )
●
    vector$i から trapasm.S の alltraps() に飛ぶ
(2) 割り込みハンドラの処理
●
    trapasm.S alltraps




                         ・自動に退避されないレジスタを退避
                         ・カーネル用セグメントの設定
                         ・最終的に trap.c の trap()を呼ぶ
(2) 割り込みハンドラの処理

●
     trap.c の trap() でそれぞれの処理に応じた割り込み処
     理をおこなう
     (割り込みハンドラごとに処理をおこなっていない)
●
     タイマ割り込みの場合 CPU 時間切れなら proc.c の yield()を呼ぶ
●
     yield()からさらに proc.cの shced()が呼ばれる




    タイマ割り込み → vectors.S#vector$i() → trapasm.S#alltraps()
    → trap.c#trap() → proc.c#yield() → proc.c#shced()
(2) 割り込みハンドラの処理
●
    proc.c の sched()
    スケジューラプロセスにコンテキストスイッチする


                   ・proc‥現在のプロセスの情報をも
                   つ構造体
                   ・cpu‥各CPUが持つCPUの情報を
                   もつ構造体
                   それぞれproc.h で定義




                             コンテキストの切り替え
                   •swtch()からの戻り先 (cpu->scheduler.eip)
                    は proc.c の scheduler()
(3) スケジューラの処理   proc.c
                scheduler()




                   次に実行するプロセス
                   を探す(ラウンドロビン)




                  メモリ空間の切り替え
                  選択したプロセスにswtch()
★                  sched()のswtch()から
                   の戻り先
                   メモリ空間をカーネル用
                   に切り替え
(3) スケジューラの処理

●
    何故sched()のswtch()からscheduler()に戻るのか?
    → ブートローダから呼ばれることになる main.c の
    main()でinitプロセス(proc[0])を起動後shceduler()を呼
    ぶため
(4) 割り込みハンドラの処理(後半)
    ●
        proc.c の sched()
        scheduler() から swtch() によって選択されたプロセスの再開




★
                                   ここから処理が再開
(4) 割り込みハンドラの処理(後半)

●
    最終的にalltrap() まで return し,そこで iret して割り込み終了
●
    iret でスタックからプロセスの状態を復帰させる.このとき特権レ
    ベルも3に戻る
    スタックが切り替わっているので別のプロセス状態に戻る

    trapasm.S
                                    メモリ
                               %eip
                               %cs
                               %eflags
                               %esp
                               %ss
xv6のコンテキストスイッチの流れ(再掲)


ユーザプロセス1                                ユーザプロセス2

    タイマ割り込み                                 iret
                
割り込みハンドラ             スケジューラ             割り込みハンドラ
           swtch()            swtch()
まとめ

●
    PDP11がいやな人はxv6読んでみたらどうでしょうか
●
    いろいろと改造のしどころ有り

More Related Content

PPTX
ゼロから始める自作 CPU 入門
Hirotaka Kawata
 
PDF
Quick and Easy Device Drivers for Embedded Linux Using UIO
Chris Simmonds
 
PDF
30分で分かる!OSの作り方 ver.2
uchan_nos
 
PDF
x86とコンテキストスイッチ
Masami Ichikawa
 
PPTX
30分で分かる!OSの作り方
uchan_nos
 
PDF
私とOSSの25年
MITSUNARI Shigeo
 
PPTX
Verilator勉強会 2021/05/29
ryuz88
 
PPTX
UEFIによるELFバイナリの起動
uchan_nos
 
ゼロから始める自作 CPU 入門
Hirotaka Kawata
 
Quick and Easy Device Drivers for Embedded Linux Using UIO
Chris Simmonds
 
30分で分かる!OSの作り方 ver.2
uchan_nos
 
x86とコンテキストスイッチ
Masami Ichikawa
 
30分で分かる!OSの作り方
uchan_nos
 
私とOSSの25年
MITSUNARI Shigeo
 
Verilator勉強会 2021/05/29
ryuz88
 
UEFIによるELFバイナリの起動
uchan_nos
 

What's hot (20)

PDF
[Container Runtime Meetup] runc & User Namespaces
Akihiro Suda
 
PDF
Interrupt Affinityについて
Takuya ASADA
 
PDF
ACRiウェビナー:小野様ご講演資料
直久 住川
 
PDF
FPGA+SoC+Linux実践勉強会資料
一路 川染
 
PDF
LAS16 111 - Raspberry pi3, op-tee and jtag debugging
96Boards
 
PDF
20111015 勉強会 (PCIe / SR-IOV)
Kentaro Ebisawa
 
PPTX
大規模分散システムの現在 -- Twitter
maruyama097
 
PDF
WebAssembly向け多倍長演算の実装
MITSUNARI Shigeo
 
PDF
明日使えないすごいビット演算
京大 マイコンクラブ
 
PDF
ARM Trusted FirmwareのBL31を単体で使う!
Mr. Vengineer
 
PDF
New Ways to Find Latency in Linux Using Tracing
ScyllaDB
 
PDF
Capturing NIC and Kernel TX and RX Timestamps for Packets in Go
ScyllaDB
 
PDF
WebAssemblyのWeb以外のことぜんぶ話す
Takaya Saeki
 
PDF
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
 
PDF
HKG15-311: OP-TEE for Beginners and Porting Review
Linaro
 
PDF
SSE4.2の文字列処理命令の紹介
MITSUNARI Shigeo
 
PDF
エンジニアなら知っておきたい「仮想マシン」のしくみ (BPStudy38)
Takeshi HASEGAWA
 
PDF
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka
 
PDF
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
 
PPTX
initとプロセス再起動
Takashi Takizawa
 
[Container Runtime Meetup] runc & User Namespaces
Akihiro Suda
 
Interrupt Affinityについて
Takuya ASADA
 
ACRiウェビナー:小野様ご講演資料
直久 住川
 
FPGA+SoC+Linux実践勉強会資料
一路 川染
 
LAS16 111 - Raspberry pi3, op-tee and jtag debugging
96Boards
 
20111015 勉強会 (PCIe / SR-IOV)
Kentaro Ebisawa
 
大規模分散システムの現在 -- Twitter
maruyama097
 
WebAssembly向け多倍長演算の実装
MITSUNARI Shigeo
 
明日使えないすごいビット演算
京大 マイコンクラブ
 
ARM Trusted FirmwareのBL31を単体で使う!
Mr. Vengineer
 
New Ways to Find Latency in Linux Using Tracing
ScyllaDB
 
Capturing NIC and Kernel TX and RX Timestamps for Packets in Go
ScyllaDB
 
WebAssemblyのWeb以外のことぜんぶ話す
Takaya Saeki
 
ゼロからはじめるKVM超入門
VirtualTech Japan Inc.
 
HKG15-311: OP-TEE for Beginners and Porting Review
Linaro
 
SSE4.2の文字列処理命令の紹介
MITSUNARI Shigeo
 
エンジニアなら知っておきたい「仮想マシン」のしくみ (BPStudy38)
Takeshi HASEGAWA
 
C++コミュニティーの中心でC++をDISる
Hideyuki Tanaka
 
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
 
initとプロセス再起動
Takashi Takizawa
 
Ad

Viewers also liked (20)

PDF
あなたの知らないネットワークプログラミングの世界
Ryousei Takano
 
PPTX
An other world awaits you
信之 岩永
 
PDF
Kernel vm study_2_xv6_scheduler_part1_revised
Toshiaki Nozawa
 
PDF
πολλαπλασιασμοι ενοτητα 11
Γιαννόπουλος Γιάννης
 
PDF
とある帽子の大蛇料理Ⅱ
Masami Ichikawa
 
PPTX
Bish Bash Bosh & Co
Bish Bash Bosh & Co
 
PDF
100Gbpsソフトウェアルータの実現可能性に関する論文
y_uuki
 
PDF
User-space Network Processing
Ryousei Takano
 
PDF
デバドラを書いてみよう!
Masami Ichikawa
 
PDF
I/O仮想化最前線〜ネットワークI/Oを中心に〜
Ryousei Takano
 
PDF
Disruptive IP Networking with Intel DPDK on Linux
Naoto MATSUMOTO
 
PDF
クラウド環境におけるキャッシュメモリQoS制御の評価
Ryousei Takano
 
PDF
DPDKを拡張してみた話し
Lagopus SDN/OpenFlow switch
 
PDF
Async deepdive before de:code
Kouji Matsui
 
PDF
continuatioN Linking
Kouji Matsui
 
PDF
これからの「async/await」の話をしよう
Kouji Matsui
 
PDF
async/awaitダークサイド is 何
Kouji Matsui
 
PDF
Xeon dとlagopusと、pktgen dpdk
Masaru Oki
 
PDF
Dpdk環境の話
Masaru Oki
 
PDF
async/await不要論
bleis tift
 
あなたの知らないネットワークプログラミングの世界
Ryousei Takano
 
An other world awaits you
信之 岩永
 
Kernel vm study_2_xv6_scheduler_part1_revised
Toshiaki Nozawa
 
πολλαπλασιασμοι ενοτητα 11
Γιαννόπουλος Γιάννης
 
とある帽子の大蛇料理Ⅱ
Masami Ichikawa
 
Bish Bash Bosh & Co
Bish Bash Bosh & Co
 
100Gbpsソフトウェアルータの実現可能性に関する論文
y_uuki
 
User-space Network Processing
Ryousei Takano
 
デバドラを書いてみよう!
Masami Ichikawa
 
I/O仮想化最前線〜ネットワークI/Oを中心に〜
Ryousei Takano
 
Disruptive IP Networking with Intel DPDK on Linux
Naoto MATSUMOTO
 
クラウド環境におけるキャッシュメモリQoS制御の評価
Ryousei Takano
 
DPDKを拡張してみた話し
Lagopus SDN/OpenFlow switch
 
Async deepdive before de:code
Kouji Matsui
 
continuatioN Linking
Kouji Matsui
 
これからの「async/await」の話をしよう
Kouji Matsui
 
async/awaitダークサイド is 何
Kouji Matsui
 
Xeon dとlagopusと、pktgen dpdk
Masaru Oki
 
Dpdk環境の話
Masaru Oki
 
async/await不要論
bleis tift
 
Ad

Similar to xv6のコンテキストスイッチを読む (10)

PDF
PFI Seminar 2010/02/18
Preferred Networks
 
PDF
V6read#3
magoroku Yamamoto
 
PDF
d-kami x86-1
Daisuke Kamikawa
 
PDF
2011.09.18 v7から始めるunix まとめ
Makiko Konoshima
 
PDF
初めてのCPUを作ってみた
Eric Sartre
 
PDF
mbedではじめる組み込みHaskellプログラミング
Kiwamu Okabe
 
PPTX
もしも… Javaでヘテロジニアスコアが使えたら…
Yasumasa Suenaga
 
PDF
V6 unix in okinawa
magoroku Yamamoto
 
PDF
Tora pointer3
MARISHI
 
PDF
llvm入門
MITSUNARI Shigeo
 
PFI Seminar 2010/02/18
Preferred Networks
 
d-kami x86-1
Daisuke Kamikawa
 
2011.09.18 v7から始めるunix まとめ
Makiko Konoshima
 
初めてのCPUを作ってみた
Eric Sartre
 
mbedではじめる組み込みHaskellプログラミング
Kiwamu Okabe
 
もしも… Javaでヘテロジニアスコアが使えたら…
Yasumasa Suenaga
 
V6 unix in okinawa
magoroku Yamamoto
 
Tora pointer3
MARISHI
 
llvm入門
MITSUNARI Shigeo
 

More from mfumi (12)

PDF
MMDs 12.3 SVM
mfumi
 
PDF
MMDs10.6-7
mfumi
 
PDF
IA16 2
mfumi
 
PDF
IA16
mfumi
 
PDF
IA14
mfumi
 
PDF
木を綺麗に描画するアルゴリズム
mfumi
 
PDF
MMDs Chapter 9
mfumi
 
PDF
グラフを奇麗に描画するアルゴリズム
mfumi
 
PDF
Algorithms Introduction 9章
mfumi
 
PDF
MMDs 6.3-6.5
mfumi
 
PDF
MMDs Chapter 5.1 PageRank
mfumi
 
PDF
ファイルの隠し方
mfumi
 
MMDs 12.3 SVM
mfumi
 
MMDs10.6-7
mfumi
 
IA16 2
mfumi
 
IA16
mfumi
 
IA14
mfumi
 
木を綺麗に描画するアルゴリズム
mfumi
 
MMDs Chapter 9
mfumi
 
グラフを奇麗に描画するアルゴリズム
mfumi
 
Algorithms Introduction 9章
mfumi
 
MMDs 6.3-6.5
mfumi
 
MMDs Chapter 5.1 PageRank
mfumi
 
ファイルの隠し方
mfumi
 

Recently uploaded (11)

PDF
【学会聴講報告】CVPR2025からみるVision最先端トレンド / CVPR2025 report
Sony - Neural Network Libraries
 
PDF
20250730_QiitaBash_LT登壇資料_PDC_Kurashina.pdf
pdckurashina
 
PDF
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
PPTX
2025_7_25_吉祥寺_設計ナイト_ADR運用におけるデータ利活用の考え方.pptx
ssuserfcafd1
 
PDF
TaketoFujikawa_ComicComputing12th_inKumamoto
Matsushita Laboratory
 
PDF
20250729_Devin-for-Enterprise
Masaki Yamakawa
 
PPTX
baserCMS『カスタムコンテンツ』徹底活用術〜あなただけの管理画面を自由自在に〜
Ryuji Egashira
 
PDF
20250726_Devinで変えるエンプラシステム開発の未来
Masaki Yamakawa
 
PDF
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
PDF
MahiroYoshida_セリフに着目したキャラクタロール推定に関する基礎検討_sigcc12th2025
Matsushita Laboratory
 
PDF
LoRaWAN ウェザーステーションキット v3 -WSC3-L 日本語ユーザーマニュアル
CRI Japan, Inc.
 
【学会聴講報告】CVPR2025からみるVision最先端トレンド / CVPR2025 report
Sony - Neural Network Libraries
 
20250730_QiitaBash_LT登壇資料_PDC_Kurashina.pdf
pdckurashina
 
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
2025_7_25_吉祥寺_設計ナイト_ADR運用におけるデータ利活用の考え方.pptx
ssuserfcafd1
 
TaketoFujikawa_ComicComputing12th_inKumamoto
Matsushita Laboratory
 
20250729_Devin-for-Enterprise
Masaki Yamakawa
 
baserCMS『カスタムコンテンツ』徹底活用術〜あなただけの管理画面を自由自在に〜
Ryuji Egashira
 
20250726_Devinで変えるエンプラシステム開発の未来
Masaki Yamakawa
 
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
MahiroYoshida_セリフに着目したキャラクタロール推定に関する基礎検討_sigcc12th2025
Matsushita Laboratory
 
LoRaWAN ウェザーステーションキット v3 -WSC3-L 日本語ユーザーマニュアル
CRI Japan, Inc.
 

xv6のコンテキストスイッチを読む

  • 2. 自己紹介 ● セキュリティキャンプ2012OS組
  • 3. 最近こんな本が出ました はじめてのOSコードリーディング 青柳隆宏著 おすすめ! でも...
  • 4. UNIX V6 を読む上で大変なところ ● PDP11 ● Cの記法が古い (pre K&R) ● アセンブラの記法が特殊 ● デフォルトが8進数 ● etc...
  • 5. xv6とは ● MITで開発された教育用OS http://pdos.csail.mit.edu/6.828/2012/xv6.html ● UNIX V6 を x86 向けに書き直したもの ● 解説書有り http://pdos.csail.mit.edu/6.828/2012/xv6/book- rev7.pdf
  • 6. xv6の特徴 ● x86 ● マルチプロセッサ対応 ● バイナリはELF ● スワッピング機能はなし ● qemu+gdb で動作可
  • 7. コンテキストスイッチ ● プロセスのコンテキストを切り替える ● コンテキスト … – メモリ空間 → cr3 レジスタを切り替える – スタック → %esp を切り替える – 各種レジスタ → プロセスごとのスタックに退避&スタックから復帰
  • 8. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); • proc.h
  • 9. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ % % % ★ % %esp %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 10. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ %edi %esi %ebx %esp ★ %ebp %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 11. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ %edi %esi %esp %ebx ★ %ebp %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 12. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ %edi %esp %esi %ebx %ebp ★ %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 13. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ %esp %edi %esi %ebx %ebp %eip(swtchの戻り先) ★ new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 14. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ %esp %edi *old(%eax) %esi %ebx %ebp %eip(swtchの戻り先) ★ new(%edx) %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 15. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ *old(%eax) %edi %esi %ebx %ebp %eip(swtchの戻り先) %esp new(%edx) ★ %edi %esi %ebx %ebp %eip(swtchの戻り先)
  • 16. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ *old(%eax) %edi %esi %ebx %ebp %eip(swtchの戻り先) new(%edx) %edi %esp %esi %ebx ★ %ebp %eip(swtchの戻り先)
  • 17. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ *old(%eax) %edi %esi %ebx %ebp %eip(swtchの戻り先) new(%edx) %edi %esi %esp %ebx %ebp ★ %eip(swtchの戻り先)
  • 18. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ *old(%eax) %edi %esi %ebx %ebp %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %esp %ebp %eip(swtchの戻り先) ★
  • 19. xv6のコンテキストスイッチ • switch.S void swtch(struct context **old, struct context *new); メモリ *old(%eax) %edi %esi %ebx %ebp %eip(swtchの戻り先) new(%edx) %edi %esi %ebx %ebp %esp %eip(swtchの戻り先) ★
  • 20. xv6のコンテキストスイッチの流れ ユーザプロセス1 ユーザプロセス2 タイマ割り込み iret   割り込みハンドラ スケジューラ 割り込みハンドラ swtch() swtch()
  • 21. (1) 割り込みの発生 ● xv6では100msごとにタイマ割り込みが発生 ● 割り込みが発生すると – 特権レベルが3から0に移行 – スタックがカーネルスタックに切り替わる (TSSからカーネル用%espと%ssを読み込む) – スタックに%ss, %esp, %eflags, %cs, %eip を積む (現在実行していたプロセスの状態を積む) – 対応する割り込みハンドラに移行
  • 22. (1) 割り込みの発生 xv6では ● vectors.S (vectors.plから生成される) 内に定義してあ る vector$i() ($iは割り込み番号) が呼び出される (割り込みハンドラの設定は trap.c の tvinit(), idtinit(), いずれも main.c のmain()から呼ばれる ) ● vector$i から trapasm.S の alltraps() に飛ぶ
  • 23. (2) 割り込みハンドラの処理 ● trapasm.S alltraps ・自動に退避されないレジスタを退避 ・カーネル用セグメントの設定 ・最終的に trap.c の trap()を呼ぶ
  • 24. (2) 割り込みハンドラの処理 ● trap.c の trap() でそれぞれの処理に応じた割り込み処 理をおこなう (割り込みハンドラごとに処理をおこなっていない) ● タイマ割り込みの場合 CPU 時間切れなら proc.c の yield()を呼ぶ ● yield()からさらに proc.cの shced()が呼ばれる タイマ割り込み → vectors.S#vector$i() → trapasm.S#alltraps() → trap.c#trap() → proc.c#yield() → proc.c#shced()
  • 25. (2) 割り込みハンドラの処理 ● proc.c の sched() スケジューラプロセスにコンテキストスイッチする ・proc‥現在のプロセスの情報をも つ構造体 ・cpu‥各CPUが持つCPUの情報を もつ構造体 それぞれproc.h で定義 コンテキストの切り替え •swtch()からの戻り先 (cpu->scheduler.eip) は proc.c の scheduler()
  • 26. (3) スケジューラの処理 proc.c scheduler() 次に実行するプロセス を探す(ラウンドロビン) メモリ空間の切り替え 選択したプロセスにswtch() ★ sched()のswtch()から の戻り先 メモリ空間をカーネル用 に切り替え
  • 27. (3) スケジューラの処理 ● 何故sched()のswtch()からscheduler()に戻るのか? → ブートローダから呼ばれることになる main.c の main()でinitプロセス(proc[0])を起動後shceduler()を呼 ぶため
  • 28. (4) 割り込みハンドラの処理(後半) ● proc.c の sched() scheduler() から swtch() によって選択されたプロセスの再開 ★ ここから処理が再開
  • 29. (4) 割り込みハンドラの処理(後半) ● 最終的にalltrap() まで return し,そこで iret して割り込み終了 ● iret でスタックからプロセスの状態を復帰させる.このとき特権レ ベルも3に戻る スタックが切り替わっているので別のプロセス状態に戻る trapasm.S メモリ %eip %cs %eflags %esp %ss
  • 30. xv6のコンテキストスイッチの流れ(再掲) ユーザプロセス1 ユーザプロセス2 タイマ割り込み iret   割り込みハンドラ スケジューラ 割り込みハンドラ swtch() swtch()
  • 31. まとめ ● PDP11がいやな人はxv6読んでみたらどうでしょうか ● いろいろと改造のしどころ有り