Slide 1

Slide 1 text

全ての (Web) エンジニアに 知ってもらいたいOSの中身 builderscon tokyo 2018 2018-09-08 (Sat) 10:00-11:00 / Track-C @ariaki4dev CC-BY-4.0

Slide 2

Slide 2 text

About Me 森川 晃 / ariaki MEDIA DO Co., Ltd. ariaki4dev [email protected]

Slide 3

Slide 3 text

問題提起

Slide 4

Slide 4 text

あなたはどんなOSを使ってますか? 思い浮かべてください

Slide 5

Slide 5 text

あなたはサーバOSを 最近インストールしましたか?

Slide 6

Slide 6 text

Desktop OS (Jul, 2018) Website OS (Jul, 2018) 現在のOSシェア https://netmarketshare.com/operating-system-market-share.aspx https://w3techs.com/technologies/overview/operating_system/all

Slide 7

Slide 7 text

Desktop OS (Jul, 2018) Website OS (Jul, 2018) https://netmarketshare.com/operating-system-market-share.aspx https://w3techs.com/technologies/overview/operating_system/all 昔と比べて認知度が下がった(気がする) 現在のOSシェア

Slide 8

Slide 8 text

OS認知の低下 サーバOSの管理はもう時代遅れかな?

Slide 9

Slide 9 text

サーバOS管理の辛さを1行で表現する

Slide 10

Slide 10 text

/ 95 rm -fr --no-preserve-root / 10 setenforce 0

Slide 11

Slide 11 text

- システム構築においてOSレイヤを意識する機会が減ってきた - パブリッククラウドサービスの台頭 - システム動作環境のコンテナ化 - PaaS ( Platform as a Service ) - FaaS ( Function as a Service ) - OSに対する価値の変化が顕著になってきた / 環境の変化 OS認知の低下

Slide 12

Slide 12 text

- 業界全体でエンジニアの割合が変化した Web系のエンジニアが急増 機械学習やビッグデータ等のエンジニアも増えている アセンブラやC言語の認知率が低下 - ハード/ソフト両面の高度化が進み、理解の難易度が上がった / エンジニアの変化 OS認知の低下

Slide 13

Slide 13 text

ちょっと待って!

Slide 14

Slide 14 text

あなたが作るプログラムはすべて OSの上で動いています

Slide 15

Slide 15 text

OSを知るとちょっと幸せになれる (かも)

Slide 16

Slide 16 text

プログラムが動く仕組みがちょっとわかる プログラムエラーの中身がちょっとわかる OSの役割がちょっとわかる そうだ、Linux Kernelを読んでみよう

Slide 17

Slide 17 text

OSの中身をちょっと理解した OSが自作できるようになった にちょっと興味もった

Slide 18

Slide 18 text

開 演

Slide 19

Slide 19 text

ブートシーケンスから OSの動きを紐解く

Slide 20

Slide 20 text

/ 95 仮想8086モード リアルモード プロテクトモード ロングモード 16bit 32bit 64bit BIOSブート時のCPU動作モード 電源ON 互換モード Legacy Mode 20

Slide 21

Slide 21 text

CPU動作モード? 歴史的背景 16bit リアルモード 32bit プロテクトモード 仮想8086モード 64bit ロングモード (64bitモード) 互換モード

Slide 22

Slide 22 text

昔々、ある所に・・・

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

- 1978年に発売された初めての16bit CPU - 利用可能な物理メモリ1MB Intel 8086

Slide 27

Slide 27 text

リアルモード is ※現在のCPUはあくまで互換仕様なので改良されています

Slide 28

Slide 28 text

is プロテクトモード ※現在のCPUはあくまで互換仕様なので改良されています

Slide 29

Slide 29 text

1982 1985 8086 1978 1980 1989 ・・・ 2004 80286 80386 80486 16bit 32bit 64bit x64

Slide 30

Slide 30 text

/ 95 40年前のCPUと互換動作すんの? え、まじ? 30

Slide 31

Slide 31 text

https://2it201jv.wordpress.com/2014/01/13/8086-pin-diagram/ Intel 8086

Slide 32

Slide 32 text

https://2it201jv.wordpress.com/2014/01/13/8086-pin-diagram/ A『アドレスバス』 AD『データバス』 20bit出力用(1,048,576通り) 16bit入出力(65,536通り) Intel 8086 - 16bit Register - 16bit CPU - 1MB Memory

Slide 33

Slide 33 text

セグメント セグメント メモリ : 1 MB 可変長/最大64KB Intel 8086 コンベンショナルエリア UMA : Upper Memory Area (予約領域) 640KB

Slide 34

Slide 34 text

セグメント セグメント メモリ : 1 MB 可変長/最大64KB コンベンショナルエリア UMA : Upper Memory Area (予約領域) 640KB Intel 80286(余談) HMA 64KB 完全にバグだったもの

Slide 35

Slide 35 text

Intel 8086 CPU レジスタ メモリ セグメント 高速 > 低速 16bit (整数レジスタ) / レジスタ CPU の中でデータを保持する箱 = + X と Y の箱が必要 X X Y レジスタって?

Slide 36

Slide 36 text

Intel 8086 / レジスタ 汎用レジスタ データ記憶や演算用 セグメントレジスタ メモリセグメント計算用 0 15 15 8 7 Flag IP CS DS SS ES SP BP SI DI AX BX CX DX - 32bit : 先頭にEがつく 例)AX → EAX - 64bit : 先頭にRがつく 例)AX → RAX 0

Slide 37

Slide 37 text

リアルモード プロテクトモード - 16bit - RAMに自由アクセス - RAM 640KBを利用可能 - 32bit - RAMにアクセス制限 - RAM 4GBを利用可能 ロングモード - 64bit - RAMにアクセス制限 - RAM 1TBを利用可能 ※理論上は1PBまで (※80286以外)

Slide 38

Slide 38 text

リアルモード is FREEDOM - メモリどこでも読める - メモリどこでも書ける - 明らかにヤバそう

Slide 39

Slide 39 text

- 16bit CPU - 利用可能メモリが16MBに増加 - プロテクトモード - マルチタスク実装 Intel 80286

Slide 40

Slide 40 text

/ 95 is 特権管理 - リングプロテクション - メモリ保護 - TSS : プロテクトモード 40

Slide 41

Slide 41 text

特権管理 メモリ管理 タスク管理 解説タイム

Slide 42

Slide 42 text

特権管理 メモリ管理 タスク管理 解説タイム

Slide 43

Slide 43 text

特権管理 特権命令 Ring 3 Ring 2 Ring 1 Ring 0 Device drivers Device drivers Applications Kernel 低 高 権限 リングプロテクション

Slide 44

Slide 44 text

Ring 0 ※あくまでイメージです※

Slide 45

Slide 45 text

Ring-3 Ring-2 Ring-1 Ring-0 特権管理 Call-Gate方式 ※x64では通常使用されない システムコール (※後述)

Slide 46

Slide 46 text

一般保護例外 メモリ OS アプリ-A アプリ-B ( Ring-0 ) ( Ring-3 ) ( Ring-3 ) アプリ-A 一般保護例外 ( GPF : General Protection Fault ) ページフォルト ( PF : Page Fault )

Slide 47

Slide 47 text

Segmentation Fault - Segmentation Fault - SYSSEGVシグナルに紐付くいずれかの例外が発生した(※Linux) - 一般保護例外 - CPU保護機構に基づく権限的な例外が発生した - Segmentation Faultの一種 - 混同しがち(※自分的に)

Slide 48

Slide 48 text

特権管理 メモリ管理 タスク管理 解説タイム

Slide 49

Slide 49 text

メモリ管理 メモリ この位置のデータが欲しい

Slide 50

Slide 50 text

/ 95 メモリ管理 メモリ この範囲の中から指定しよう →『ページ』(4KB / 4MB) 50

Slide 51

Slide 51 text

メモリ管理 メモリ この区画の中から指定しよう →『PTE』(ページ × N個の集合)

Slide 52

Slide 52 text

メモリ管理 メモリ 更に大きな区画の中から指定しよう →『PDE』(PTE × N個の集合)

Slide 53

Slide 53 text

メモリ管理 / ページング リニアアドレス空間 ページ リニアアドレス PDE PTE OFFSET PDE PTE ※PDE毎に1ページのサイズを4KB/4MBから選択できる ※PDEを複数段に分割管理する場合がある

Slide 54

Slide 54 text

メモリ管理 リニアアドレス空間 リニアアドレスをまとめた区画 →『セグメント』 PDE PTE OFFSET

Slide 55

Slide 55 text

メモリ管理 / セグメンテーション GDT リニアアドレス空間 セグメント セグメントベース リミット値 特権レベル(DPL) Segment Descriptor : 実行時権限(CPL)と比較される 最大8,192個 リニアアドレス ※現在多くのOSでは、メモリ全体を1つのセグメントとしている 論理アドレス OFFSET SEGMENT

Slide 56

Slide 56 text

- ページング - セグメンテーション メモリ管理

Slide 57

Slide 57 text

特権管理 メモリ管理 タスク管理 解説タイム

Slide 58

Slide 58 text

タスク管理 / マルチタスク タスク-B タスク-A コンテキストスイッチ タイムスライス タイマ割込

Slide 59

Slide 59 text

タスク管理 タスク生成 実行可能状態 入出力要求 (スーパーバイザコール) 待ち状態 実行状態 ディスパッチャ 入出力完了 (待機完了) プリエンプション ディスパッチング タスク終了 / プリエンプティブ 各タスクの状態はTSS : Task State Segmentによって管理される

Slide 60

Slide 60 text

/ 95 60 だいたい全編CPUの話 してる気がする

Slide 61

Slide 61 text

脱線しすぎた (既定路線)

Slide 62

Slide 62 text

ブートシーケンスから OSの動きを紐解く ここから本気出す

Slide 63

Slide 63 text

BIOS起動の場合 ブートシーケンス BIOS Bootstrap Loader Kernel Loader Kernel MBR = 512バイト 最低限の初期化処理 カーネルロードに 必要な初期化処理 カーネル本体

Slide 64

Slide 64 text

BIOS起動 1 POST : Power On Self Test 実行 2 ブートストラップローダを実行 3 a) INT 0x19 ( Bootstrap Routine) を発行 b) INT 0x13 ( Disk Services ) を発行 c) ブートディスクの先頭セクタ(MBR : Master Boot Record)を 0x7c00 に読み込む →失敗時は INT 0x18 ( Boot Fault Routine ) 発行 d) ブートレコードの末尾が 0x55AA ( Boot Signature ) である事を確認する e) ロードされたメモリ領域へ FAR ジャンプ ブートシーケンス 後で説明

Slide 65

Slide 65 text

0x7c00 なんだろう?

Slide 66

Slide 66 text

0x7c00の起源 - IBM PC 5150(1981年発売)のROM BIOSが起源 - David Bradley氏が開発(※Ctrl-Alt-Delete実装した人) - 以前のOS “86-DOS”の実装は知らなかった - DOS 1.0は最小で32KBのメモリを必要としていた - 先頭の方は予約されていて使えない - じゃあメモリ末尾(32KB)にロードしよう - MBR自体が512バイト+MBRが使うデータ領域に512バイト - 32k - 512 - 512 = 0x7c00 【参考記事】なぜx86ではMBRが"0x7C00"にロードされるのか?(完全版) https://www.glamenv-septzen.net/view/614

Slide 67

Slide 67 text

INT 0x19 なんだろう?

Slide 68

Slide 68 text

INT = 割込 CPU ハードウェア ソフトウェア Kernel

Slide 69

Slide 69 text

INT = 割込 CPU ソフトウェア システムコール ソフトウェアが自身の実行権限(Ring-3)を超 えて上位の機能を呼び出す

Slide 70

Slide 70 text

/ 95 INT = 割込 割込コントローラ タイマIC ディスクコントローラ キーボードコントローラ CPU ハードウェアの動作状況をCPUを通じてOSに 通知する 70

Slide 71

Slide 71 text

INT = 割込 割込の種類 命令 ソフトウェア割込 ユーザプログラムがシステムコールを呼び出す ハードウェア割込(IRQ) 周辺機器からの信号(InterRupt reQuest)によって発生する 例外 TRAP INT, INTO命令の実行によって発生する FAULT 保護機能、MMUのチェックによって発生する ABORT 処理を続けられないエラーによって発生する 強 弱

Slide 72

Slide 72 text

例外の種類 1/2 番号 名称 種類 シグナル 説明 0 除算エラー FAULT SIGFPE 0で除算された 1 デバッグ例外 TRAP SIGTRAP デバッグ中に発生(ステップ実行) 3 ブレークポイント TRAP SIGTRAP デバッグ中に発生 4 オーバーフロー TRAP SIGSEGV 桁あふれが発生した 5 BOUND範囲超過 FAULT SIGSEGV アドレス有効範囲外のコードを実行した 6 無効オペコード FAULT SIGILL 無効なオペコードを検出した 7 デバイス使用不能 FAULT ── CR0レジスタTSフラグによって発生 8 ダブルフォルト ABORT ── CPUが連続した例外を処理できない場合に発生 9 コプロセッサセグメン トオーバーラン ABORT SIGFPE 外部算術演算コプロセッサによって発生(80386限定) Segmentation Fault

Slide 73

Slide 73 text

例外の種類 2/2 番号 名称 種類 シグナル 説明 10 無効TSS FAULT SYSSEGV 無効なTSSを持つプロセスに切り替えた 11 セグメント不在 FAULT SIGBUS メモリ中に存在しないセグメントを参照した 12 スタックフォルト FAULT SIGBUS 命令がスタックセグメントの範囲を超えた 13 一般保護 FAULT SYSSEGV プロテクトモードの保護規則に違反した 14 ページフォルト FAULT SYSSEGV 参照されたページへのアクセスが拒否された 16 浮動小数点エラー FAULT SYSFPE 浮動小数点演算に失敗した 17 アライメントチェック FAULT SYSBUS オペランドのアドレスが正しくアラインされていない 18 マシンチェック ABORT ── マシンチェック機構がCPUやバスエラーを検出 19 SIMD浮動小数点 FAULT SYSFPE SSE/SSE2回路が浮動小数点演算でエラーを検出 General Protection Fault

Slide 74

Slide 74 text

Kernel User Land Operating System Application User Hardware ライブラリ システムコール 時間管理 メモリ管理 タスク管理 ドライバ シェル アクセサリ ファイル管理

Slide 75

Slide 75 text

Demonstration Hello, World ! - 実行環境:CentOS 7.5 - 使用言語:gcc - デバッガ:gdb

Slide 76

Slide 76 text

Demonstration gcc -Wall -O0 -ggdb3 -o hello hello.c コンパイル: [ hello.c ]

Slide 77

Slide 77 text

Demonstration ltrace ./hello

Slide 78

Slide 78 text

Demonstration strace ./hello

Slide 79

Slide 79 text

Demonstration gdb → ステップ実行 → layout asm 【参考記事】 Linuxカーネルに見る、システムコール番号と引数、システムコール・ラッパーとは http://www.atmarkit.co.jp/ait/articles/1703/01/news171.html

Slide 80

Slide 80 text

/ 95 システムコール - システムコールを発行する方法は 3 種類 - SYSCALL 新しい方法、AMD発、古いCPUでは対応していない - SYSENTER 新しい方法、Intel発、古いCPUでは対応していない - INT 0x80 最も古い方法、特化していないのでオーバーヘッド多い - EAXの値によって呼び出される機能が異なる - 特権が必要な処理をOSに要求する(Call-Gate方式) 80

Slide 81

Slide 81 text

システムコールの流れ(超要約版) Kernel Program CPU write() system_call() 処理開始 system_call_table 命令実施 システムコール sys_read() sys_write() sys_open() sys_close() :

Slide 82

Slide 82 text

システムコールの定義 https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_64.tbl

Slide 83

Slide 83 text

system_call_table 1/2 0 1 2 3 : sys_read() sys_write() sys_open() sys_close() : OS起動時にメモリ上に設定しておく (※各動作モードを切替えた際)

Slide 84

Slide 84 text

system_call_table 2/2 MSR: Model Specific Register IA32_EFER IA32_STAR IA32_LSTAR IA32_CSTAR : IA32_PAT system_call_table system_call_table system_call_table レガシーモード 64bitモード 互換モード SYSENTER / SYSCALL sys_read() sys_write() sys_open() sys_close() :

Slide 85

Slide 85 text

Interrupt Descriptor Table Gate Descriptor Call Gate Descriptor IDT INT 0x80 Interrupt Gate Descriptor Task Gate Descriptor (Interrupt Descriptor Table) system_call_table #0 #1 : #128 : sys_read() sys_write() sys_open() sys_close() : Trap Gate Descriptor

Slide 86

Slide 86 text

CPUがメモリを管理する為の情報を一元管理する - Segment Descriptor - TSS Descriptor - Call Gate Descriptor 異なる特権レベル呼出に利用する - Interrupt Gate Descriptor 割込/例外処理時に利用する - Task Gate Descriptor タスクスイッチ時に利用する - Trap Gate Descriptor 割込/例外処理時に利用する : Global Descriptor Table

Slide 87

Slide 87 text

CPU動作モード Intel CPUの簡単な歴史 特権管理 メモリ管理 タスク管理 割込 システムコール 今日覚えた事

Slide 88

Slide 88 text

最後に

Slide 89

Slide 89 text

Discover Something New

Slide 90

Slide 90 text

/ 95 Discover Something New Old 90

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

Commercials

Slide 93

Slide 93 text

Go言語 初心者向けハンズオン https://techdo.connpass.com/event/100306/ 登壇の技術を勉強する会 #1 https://engineers.connpass.com/event/100460/ 9/ 9/ 14 21 沖縄Go言語LT大会 https://engineers.connpass.com/event/100437/ 10/ 4 ~ エンジニアの登壇を応援する会 出張版

Slide 94

Slide 94 text

We’re Hiring ! https://www.mediado.jp/mediado/recruit/

Slide 95

Slide 95 text

Build Something Amazing written by ariaki4dev

Slide 96

Slide 96 text

Appendix / Web Sites - Intel 80386 Reference Programmer's Manual - Linux Inside - ハードウェアの基本 - コメントから読むLinuxカーネル - ブートストラップ - パソコン実習室 - 0から作るOS開発 - OSASK計画 - OS Wiki - OS Project Wiki - Linuxをはじめよう! - OpenBSD kernel hack memo annex - アセンブラの基礎

Slide 97

Slide 97 text

Appendix / Books - 32ビットコンピュータをやさしく語る はじめて読む486 / 蒲地輝尚 - 30日でできる!OS自作入門 / 川合 秀実 - ハロー“Hello, World” OSと標準ライブラリのシゴトとしくみ / 坂井弘亮 - 新装改訂版 Linuxのブートプロセスをみる / 白崎 博生 - プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識 / 矢沢 久雄 - CPUの創りかた / 渡波 郁 - ゼロからトースターを作ってみた結果 / トーマス・トウェイツ

Slide 98

Slide 98 text

#444444, rgb(68, 68, 68) #43bdc1, rgb(67, 189, 193) #da6272, rgb(218, 98, 114) builderscon builderscon builderscon builderscon builderscon builderscon builderscon builderscon Discover Something New Journey to operating system as we should know, written by ariaki4dev