linux內核文件/內存/io

MMU 虛擬地址轉爲物理地址的硬件 (進程內存3G超出也會頁交換,到文件)
page(4K.8K內存管理基本單位) 每一個物理頁一個結構 4G會佔用20M 被用戶空間進程/動態分配內核數據/靜態內核代碼/頁高速緩存等引用node

flag 髒/鎖 ;count引用計數,0空閒 ;*virtual 虛擬地址

RAM
分區 DDMA normal highem動態映射的頁
分配:linux

alloc_pages 整個頁
kmalloc 字節 連續內存虛擬地址,物理地址也連續
vmalloc 虛擬連續,物理不必定,創建頁表項須要一個一個的映射
slab層,防止每一個進程本身單首創建free鏈,不能全局判斷
    高低度緩衝組。kmem_cache。每一個類型好比task_struct,inode,通用的。3個鏈表empty,full,parti
    kmem_Cache_alloc.內存緊缺/顯示撤銷才釋放
高端內存(頁並不必定永久映射,好比內核1G要訪問8G物理內存,動態映射)  
        kmap。可睡眠,永久映射
        kmap_atomic 臨時,原子,不睡眠,不阻塞,禁止內核搶佔
cpu上數據,alloc_percpu

Linux內核高端內存的理解
前 面咱們解釋了高端內存的由來。 Linux將內核地址空間劃分爲三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端內存HIGH_MEM地址空間範圍爲 0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。那麼如內核是如何藉助128MB高端內存地址空間是如何實現訪問能夠全部物理內存?
當內核想訪問高於896MB物理地址內存時,從0xF8000000 ~ 0xFFFFFFFF地址空間範圍內找一段相應大小空閒的邏輯地址空間,借用一會。借用這段邏輯地址空間,創建映射到想訪問的那段物理內存(即填充內核PTE頁面表),臨時用一會,用完後歸還。這樣別人也能夠借用這段地址空間訪問其餘物理內存,實現了使用有限的地址空間,訪問全部全部物理內存。緩存

1.不管CPU運行於用戶態仍是核心態,CPU執行程序所訪問的地址都是虛擬地址MMU 必須經過讀取控制寄存器CR3中的值做爲當前頁面目錄的指針,進而根據分頁內存映射機制(參看相關文檔)將該虛擬地址轉換爲真正的物理地址才能讓CPU真 正的訪問到物理地址。
2.每一個進程都有其自身的頁面目錄PGD,Linux將該目錄的指針存放在與進程對應的內存結構task_struct.(struct mm_struct)mm->pgd中。每當一個進程被調度(schedule())即將進入運行態時,Linux內核都要用該進程的PGD指針設 置CR3(switch_mm())
3.當建立一個新的進程時,都要爲新進程建立一個新的頁面目錄PGD,並從內核的頁面目錄swapper_pg_dir中複製內核區間頁面目錄項至新建進程頁面目錄PGD的相應位置
4.系統調用的具體實現是將系統調用的參數依次存入寄存器ebx,ecx,edx,esi,edi(最多5個參數,該情景有兩個 name和len),接着將系統調用號存入寄存器eax,而後經過中斷指令「int 80」使進程A進入系統空間。因爲進程的CPU運行級別小於等於爲系統調用設置的陷阱門的准入級別3,因此能夠暢通無阻的進入系統空間去執行爲int 80設置的函數指針system_call()。因爲system_call()屬於內核空間,其運行級別DPL爲0,CPU要將堆棧切換到內核堆棧,即 進程A的系統空間堆棧。咱們知道內核爲新建進程建立task_struct結構時,共分配了兩個連續的頁面,即8K的大小,並將底部約1k的大小用於 task_struct(如#define alloc_task_struct() ((struct task_struct ) __get_free_pages(GFP_KERNEL,1))),而其他部份內存用於系統空間的堆棧空間,即當從用戶空間轉入系統空間時,堆棧指針 esp變成了(alloc_task_struct()+8192),這也是爲何系統空間一般用宏定義current(參看其實現)獲取當前進程的 task_struct地址的緣由。每次在進程從用戶空間進入系統空間之初,系統堆棧就已經被依次壓入用戶堆棧SS、用戶堆棧指針ESP、EFLAGS、 用戶空間CS、EIP,接着system_call()將eax壓入,再接着調用SAVE_ALL依次壓入ES、DS、EAX、EBP、EDI、ESI、 EDX、ECX、EBX,而後調用sys_call_table+4%EAX,本情景爲sys_sethostname()
5.調用copy_from_user(to,from,n),其中to指向內核空間 system_utsname.nodename,譬如0xE625A000,from指向用戶空間譬如0x8010FE00。如今進程A進入了內核,在 系統空間中運行,MMU根據其PGD將虛擬地址完成到物理地址的映射,最終完成從用戶空間到系統空間數據的複製app

虛擬內存交換等函數

VFS 虛擬文件系統
磁盤 分區:文件,數據,交換區域
文件系統:ext2 引導塊,超級塊(包含塊大小等),i節點(可對應多級塊3IPB,2IPB等),數據atom

崩潰恢復,元數據不一致,檢查要遍歷=》日誌文件ext3,ext4

write()->sys_write(VFS)->ext2等的write->物理
文件,目錄(目錄項緩存),inode,mount point
file {鏈表,pathh file_operations}
目錄包含文件名,inode編號。目錄自身的Inode中的類型不一樣,rename僅操做目錄條目不動文件。
文件名到Inode有多個。硬連接指向一個Inode。軟連接指向文件名spa

塊IO,硬盤等,隨機訪問的,區別於字符設備只能順序訪問
塊緩衝區,已經合成一個頁緩存
塊IO請求隊列(一個塊設備一個)
調度:linusx電梯 合併請求,臨近插入線程

最終期限  超時時間(讀500ms,寫5s)三個隊列:讀FIFO/寫FIFO/排序隊列同linus=>超時派發隊列
 預測IO  超時後等幾ms,相鄰合併
 徹底公正,每一個進程一個隊列
 空IO,只合並相鄰的

clipboard.png

進程地址空間 連續虛擬地址
mm_struct 分配,撤銷……{內存區域vm_area_struct紅黑樹和鏈表,pgd,全部mm_struct鏈表,每段起始地址等}
vm_area_strict區間地址等。
虛擬地址=》物理頁面 三級頁表(pgd,pmd,pte)硬件效率有限,TLB緩存
在堆上分配,sbrk。改變programm break位置,進程能夠訪問這部分地址,若RAM未分配,內核會在進程是首次訪問這些虛擬內存地址時自動分配新RAM頁
malloc,free內找/分割,不夠sbrk指針

頁緩存(磁盤和內存ms/ns的差距)
頁告訴緩存是RAM組成,對應硬盤上的物理塊(扇區整數倍但比頁小,通常512B/1kb/4kb),
linux 寫緩存,標記髒,髒頁鏈表, 回寫進程刷會磁盤
緩存回收 LRU 雙鏈(活躍/非活躍)
address_space 每頁一個
頁內搜索 基樹。回收時要反向檢查引用的項。根據頁內偏移起終範圍找vma,起點基樹,終點堆,不少個共同引用優先搜索樹(堆+基樹)。
回寫線程flusher 一個設備一個線程,每一個收集本身的。之前固定線程數,當一個設備阻塞會阻塞其上個全部線程。由於擁塞發生次數太頻繁改一個設備一個線程。日誌

相關文章
相關標籤/搜索