Linux操做系統原理學習筆記

Linux操做系統學習總結

BIOS階段

當機器按下電源鍵通電以後,執行的第一行代碼是存儲在只讀存儲器中的BOIS程序。BIOS程序要完成的功能有:node

  1. 檢查機器各個硬件組件是否正常
  2. 檢測啓動盤

啓動盤能夠是U盤、磁盤、移動硬盤,它具備一個標識:設備的第一個扇區是引導扇區,裏面保存的是引導程序(boot.img)。引導程序會加載引導程序的各個模塊進入內存,最終會將啓動盤上的內核信息以列表的經過顯示器展現給用戶,用戶選擇一個操做系統內核以後,進入內核的啓動階段。
linux

內核啓動階段

內核啓動階段會初始化各個內核模塊,這些模塊也能夠叫作子系統。有任務管理子系統、內存管理子系統、文件管理系統等等。算法

內核程序在執行過程當中建立的第一個進程,是用戶態的進程的祖先。第二個進程是內核態全部進程的祖先。docker

內核態程序:管理硬件資源的程序,硬件資源是有限的,須要統一管理。
用戶態程序:使用硬件資源,一般是使用系統調用,運行內核程序,從而操做硬件。windows

程序執行過程

在Linux上,可執行的程序都是知足elf標準的文件。可執行程序由源代碼通過編譯獲得二進制程序,也就是elf文件。一個進程經過執行fork調用,建立一個新的進程,新的進程是子進程,而執行fork調用的進程是這個新進程的父進程,子進程再經過exec系統調用,將可執行文件加載到內存中,最終交給CPU執行。緩存

elf文件格式網絡

  • elf文件頭(文件整體描述)
  • 程序指令
  • 數據段

進程管理子系統

Linux將每一個進程都組織成一個task結構,一個task結構包含這些信息。
數據結構

  • 進程id:每一個進程都要一個id,是這個進程的惟一標識。
  • 進程狀態TASK_RUNNING(進程可執行)、TASK_INTERRPTIBLE(睡眠狀態,能夠響應中斷)、TASK_UNINTERRUPTIBLE(睡眠狀態,不可中斷,必須在條件知足以後才能夠繼續執行)、TASK_KILLABLE(睡眠狀態,不可中斷、能夠響應致命信號)、EXIT_ZOMBIE(進程執行結束,父進程還沒有獲知其終止信息)、EXIT_DEAD(進程終止狀態)
  • 進程運行統計信息:在用戶態、內核態消耗的時間、上下文切換次數等等
  • 進程間關係:父子關係、兄弟關係。
  • 進程權限信息:對文件或目錄的訪問權限、對別的進程的訪問權限、別的進程對本進程的訪問權限等。
  • 佔用的內存信息
  • 佔用的文件信息

線程

在Linux中,線程也是一個task結構,CPU最終調度的對象就是task。
分佈式

任務調度

每一個CPU有一個任務隊列,CPU在運行的時候就從隊列中取一個任務(task)出來執行。任務調度能夠有不少中調度方式,好比fifo、lru、cfs等等。經常使用的是cfs(Completely Fair Scheduling),即徹底公平調度。徹底公平調度算法依據task運行時間、優先級來保證公平。函數

調度時機:選擇具體的調度算法,解決了如何調度問題,而還有一個問題是什麼時候調度。

  • 主動讓出CPU:當一個進程執行sleep調用或者進行了阻塞IO操做,都會主動放棄CPU,在內核中就會主動執行schedule()函數來執行調度。
  • 被動讓出CPU:進程執行時間太長了,該讓出CPU給別的進程使用。這種狀況,會在如下幾個特殊時機觸發schedule()函數。
  1. 對於用戶態的進程來說,從系統調用中返回的那個時刻,是一個被搶佔的時機。
  2. 對於用戶態的進程來說,從中斷中返回的那個時刻,也是一個被搶佔的時機。
  3. 對內核態的執行中,被搶佔的時機通常發生在 preempt_enable() 中。在內核態的執行中,有的操做是不能被中斷的,因此在進行這些操做以前,老是先調用 preempt_disable() 關閉搶佔。再次打開的時候,就是一次內核態代碼被搶佔的機會。
  4. 在內核態也會遇到中斷的狀況,當中斷返回的時候,返回的仍然是內核態。這個時候也是一個執行搶佔的時機。

內存管理子系統

在Linux系統中,程序執行時訪問的指令地址、數據地址都是虛擬地址。每一個程序都覺得本身獨佔了整個物理內存。實際上,內存的每一個字節只有一個惟一的地址,不一樣程序程序對於同一個地址的訪問最終會通過頁表翻譯爲最終的物理地址,也就是虛擬地址翻譯爲物理地址。這樣,每一個程序均可以使用同一個虛擬地址,而對於同一個虛擬地址,最後會被翻譯爲不一樣的物理地址。

內存管理子系統須要完成如下功能:

  • 物理內存的管理
  • 虛擬內存的管理
  • 虛擬內存到物理內存的映射

物理內存管理:操做系統將內存分紅節點,每一個CPU先訪問離本身最近的內存節點(下圖第二種)。

每一個節點裏面再分區域(zone),用於區分不一樣的用法。每一個區域裏面再分頁,默認大小爲4KB。一個頁是每一個程序使用內存的最小單位。分配內存的時候,以一個頁的整數倍進行分配,這個整數是一、二、4...1024。當一個頁長時間不用了,能夠暫時寫到磁盤,要用的時候在讀回內存,這就是換入換出,這樣能夠增長物理內存的使用效率。

虛擬內存管理:對於每一個進程來講,內存分兩個部分,一部分由內核程序使用(稱爲內核空間),剩下的部分所有歸本身使用(稱爲用戶空間)。用戶進程不能訪問內核空間。

用戶空間的內存,分段管理,每一段存放不一樣的數據,elf格式的程序加載到內存以後,各部分對應放到各個段。內核空間裏面也會有內核的程序,一樣有 Text Segment、Data Segment和BSS Segment,內核程序也是elf格式的。

虛擬內存到物理內存的映射:將虛擬內存地址轉換爲物理內存地址,須要使用頁表。能夠簡單的將頁表理解爲一個映射結構,輸入虛擬地址,輸出物理地址。

文件系統

文件系統有兩個形態,一種形態是磁盤上的文件系統,這是在對磁盤進行格式化的時候寫入到磁盤的。另外一種形態是內核中的文件系統。內核中的文件系統定義了對磁盤上文件系統的操做以及相應的數據結構。

在文件系統中,存儲的最小單位爲塊,每一個塊默認是4KB大小。一個文件能夠拆分爲多個塊進行存放,所以須要有一個地方來記錄文件都存在於哪些塊,這是文件索引節點的須要提供的信息。

文件索引節點(inode)也是保存在塊裏面,每一個文件對應一個inode。在inode中,有如下的信息:

  • 文件讀寫權限
  • 文件屬於的用戶、用戶組
  • 文件大小
  • 文件佔用多少個塊、每一個塊的地址信息

文件夾(目錄):在文件系統的概念中,目錄也是一種文件,每一個目錄也對應一個inode。與普通文件不同的是,目錄中存放的是下一級文件的文件名和對應的inode,而普通文件裏面存放的就是數據內容。

Linux內核程序在內存中維護了一套數據結構,用來記錄哪些文件被哪些進程打開和使用,每一個進程能打開的文件數量是有上限的,所以在開發中,用完文件以後要妥善關閉文件。

輸入輸出系統

輸入輸出系統,是對IO設備的進行管理的系統。常見的IO設備分爲兩種:字符設備、塊設備。輸入輸出系統使用了層層抽象來對IO設備進行控制。

  1. 使用設備控制器屏蔽設備差別
  2. 使用設備系統程序屏蔽設備控制器差別
  3. 用中斷控制器統一處理外部事件
  4. 用文件系統接口屏蔽驅動程序的差別

進程間通訊機制

  • 管道:單向數據傳遞。將前一個程序的輸出做爲後一個程序的輸入。管道實際上以一段緩存。
  • 消息隊列
  • 共享內存 + 信號量
  • 信號:內核機制,在特殊狀況下會發出信號,用戶的程序只要準備信號處理函數就能夠處理收到的信號。

網絡通訊

不管是windows仍是linux,網絡模型是同樣的。網絡模型與具體的操做系統無關。不一樣機器之間要通訊就要經過網絡。一個應用層的信息要發送到另外一臺機器的應用,須要將消息層層包裝,加上各層協議的內容。目標機器收到網絡包以後,逐層剔除協議,再根據端口好轉發到對應的應用。

Socket是用戶態與內核態的鏈接體,用戶態的程序經過Socket接口就能夠完成網絡通訊,無需關心各層協議細節。TCP、IP協議都是在內核中實現的,不一樣的操做系統實現細節不同。

虛擬化&容器化

虛擬化就是在操做系統上運行操做系統,運用這種技術,能夠將一臺大機器虛擬爲多個小機器。比較好的一種虛擬方式是半虛擬化(硬件輔助+半虛擬化驅動),啓用硬件輔助技術以後,虛擬機的指令就能直接運行在宿主機的CPU上,不用通過翻譯。半虛擬化驅動就是指使用特殊的、更高效的IO設備驅動,提升IO效率。

集羣的操做系統

一臺物理機器,最重要的四種硬件資源是CPU、內存、存儲和網絡。對於一個集羣,好比說數據中心,如何靈活的管理和分配一堆計算資源,是一個難題。

Kubernetes,數據中心的「操做系統」,能夠靈活的實現大批的資源管理。其中,對於CPU和內存,能夠利用docker容器技術。對於存儲,不管是分佈式文件系統和分佈式塊存儲,Kubernetes提供了接口,就行提供了驅動程序接口同樣。對於網絡,一樣提供了標準接口只要對接這個統一的接口,Kubernetes 就能夠管理容器的網絡。。

docker容器技術能夠將 CPU 和內存資源,從大的資源池裏面隔離出來,並經過鏡像技術,在數據中內心面實現計算資源的自由漂移。

相關文章
相關標籤/搜索