1.inode
上老沙的課記得講過inode,但有些記不清了,這裏重新梳理一下。
一個inode對應一個文件,一個文件包含多個數據塊,數據塊不需要連續存儲。
給定一個分區,該分區的inode數量是確定的。
爲什麼呢?先看下圖再解釋
文件系統是針對各個分區來管理磁盤空間的,而分區容量是固定的,而x、y是變量,分區容量=x+y,所以x和y必須先確定一個,Linux的實現是先確定x,即給定一個分區,先算出inode數,所以對於一個分區inode的數量是確定的。
df -i 看inode利用率
df 看disk利用率
------------------------------------------------------------------------------------------------------------------------
文件類型
文件有很多種,ext2文件系統的文件類型有下圖這些
enum FILE_TYPE{
EXT2_FT_UNKNOWN, //1.未知文件類型
EXT2_FT_REG_FILE, //2.普通文件
EXT2_FT_DIR, //3.目錄文件
EXT2_FT_CHRDEV, //4.字符設備文件
EXT2_FT_BLKDEV, //5.塊設備文件
EXT2_FT_FIFO, //6.命名管道文件
EXT2_FT_SOCK, //7.套接字文件
EXT2_FT_SYMLINK, //8.符號鏈接文件
EXT2_FT_MAX; //9.文件類型的最大個數
}
文件類型爲目錄文件時,數據塊中是目錄項。
文件類型爲普通文件時,數據塊中是文件的內容。
我們知道目錄中可以有許多文件。所以目錄文件中需要用目錄項來索引這些文件的位置,每個目錄項對應目錄中的一個文件,存儲inode編號、文件名、文件類型等信息,如下圖。文件/lib的文件類型是目錄文件,目錄下有4個文件
文件組織形式:
1.鏈式結構 如Windows操作系統的FAT文件系統
文件由鏈式結構的數據塊組成。弊端:訪問某個數據塊必須要從頭遍歷數據塊,效率低。
2.索引結構 如Unix操作系統的inode
避免了訪問某一數據塊需要從頭遍歷數據塊的缺點。採用多級索引表實現
------------------------------------------------------------------------------------------------------------------------
掛載分區
掛載分區的實質是把該分區文件系統的元信息從硬盤上讀出來加載到內存中,這樣硬盤資源的變化都用內存中元信息來跟蹤,如果有寫操作,及時將內存中的元信息同步寫入到硬盤以持久化。
------------------------------------------------------------------------------------------------------------------------
2.inode、設備、文件描述符的關係
經常會疑惑inode、設備、文件描述符fd三者間的關係。不清楚stdin、stdout、stderr這三個東西究竟是設備還是文件描述符。所以在這裏把他們的關係講清楚記錄下來。
在Linux中,Everything is a file
文件描述符:
Linux 中所有文件操作都基於文件描述符fd
inode和文件描述符fd的關係:
inode : 其實也可以稱爲"文件數據塊描述符",用於描述文件的存儲位置、權限、時間等, 但inode是操作系統爲自己的文件系統準備的數據結構,它用於文件存儲的管理,與用戶關係不大。fd纔是與用戶息息相關的。
文件描述符 : Linux中所有文件操作都基於文件描述符。文件描述符是個整數,是PCB中文件描述符數組的下標。用這個數組下標去查文件表,找到對應文件結構,再通過文件結構查inode。
http://www.wangchao.net.cn/it/detail_130017.html
3.數據總線、外設、物理內存之間的關係
一直弄不清楚外設(如顯卡、鍵盤)和物理內存之間的關係。我的疑惑是下面哪種情況是對的?
1.外設會映射到物理內存中
2.把物理內存也看成一種設備,所有設備(設備 + 內存)都映射到數據總線上
真相:CSAPP書中有
設備也是一個文件,文件映射到虛擬地址的Memory Mapped Segment。
------------------------------------------------------------------------------------------------------------------------
訪問外設有兩種方式
1.將外設的內存映射到一定範圍的地址空間中
CPU 通過地址總線訪問該內存區域時會落到外設的內存中,這種映射讓 CPU 訪問外設的內存就如同訪問主板上的物理內存 樣。有的設備是這樣做的,比如顯卡,顯卡是顯示器的適配器, CPU 不直接和顯示器交互,它只和顯卡通信。顯卡上有片內存叫顯存,它被映射到主機物理內存上的低端 1MB 的0xB8000~0xBFFFF。
地址總線是什麼?
答:地址總線屬於一種電腦總線,是由CPU 或有DMA 能力的單元,用來溝通這些單元想要存取(寫入/讀取)電腦內存元件/地方的實體位址。
2.通過IO接口
外設是通過 IO 接口與 CPU 通信的, CPU 訪問外設,就是訪問 IO 接口,由 IO 接口將信息傳遞給另一端的外設,也就是說, CPU 從來不知道有這些設備的存在,它只知道自己操作的 IO 接口。
------------------------------------------------------------------------------------------------------------------------
fork實現原理,複製進程的虛擬地址空間
fork步驟,兩步走
1.複製進程資源
2.跳過去執行,讓cs:ip指向新進程的指令部分(這部分沒看懂)
進程有哪些資源:(特別重要)
(1)進程的pcb
(2)棧、文件映射(fork複製這一段可以進程間通信,方式叫共享內存)、堆、bss、data、text
(3)頁表
(4)虛擬地址池?
------------------------------------------------------------------------------------------------------------------------
Linux進程內存佈局:
1.https://blog.csdn.net/mumumuwudi/article/details/47141291
2.內核空間劃分:https://blog.csdn.net/tommy_wxie/article/details/17122923/命令行參數和環境變量
3.命令行參數和系統環境變量是在kernel space,見Unix環境高級編程(第三版)p164。
Linux中一個進程有4GB虛擬地址空間,每個進程有自己的頁表將虛擬地址映射到物理內存,每個進程使用同樣的虛擬地址而不衝突,因爲他們實際的物理地址是不同的。
內核用的是3G以上的1G虛擬內存地址,其中896M是直接映射到物理地址的,128M按需映射896M以上的所謂高位內存。各進程用的是同一個內核
------------------------------------------------------------------------------------------------------------------------
爲什麼叫"陷入內核"?
1.由於歷史原因:https://www.quora.com/Why-are-System-calls-also-called-traps
2.一個形象好記的版本:http://baijiahao.baidu.com/s?id=1589837580293384492&wfr=spider&for=pc
什麼時候會陷入內核?
粗略理解:用戶態進程通過系統調用進入內核態
詳細理解:什麼情況下線程會陷入內核態?
陷入指令是什麼?
A TRAP instruction is performed to switch from user mode to kernel mode.
baidu:陷入指令
wiki:Trap
x86架構的cpu上有條指令叫syscall,用來做這個事。
trap vs. interrupt
trap is typically a type of synchronous interrupt.(from wiki)
trap is a kind of software interrupt
https://stackoverflow.com/a/37558741
A. classes of interrupt(8086架構的中斷分類)
1.hardware interrupts
2.software interrupts
B. classes of exceptions (x86架構的異常分類,CS:APP書中有,8086太老了僅供參考)
1. interrupt(signal from I/O device,即單指硬中斷)
2. trap
3. fault
4. Abort
A、B是不同時代的分類,對syscall這條指令而言,在A分類中屬於software interrupts類別,在B分類中屬於trap類別。
------------------------------------------------------------------------------------------------------------------------
系統調用 vs. 標準I/O庫函數
常用系統調用:open, read, write, close, wait, exec, fork, exit, and kill
系統調用 | 庫函數 |
open、close | fopen、fclose |
read、write | fread、fwrite |
putc、write | printf、write |
sbrk、mmap、munmap | malloc、calloc、free |
執行man man,可以看到下圖
有標號1-9,1代表可執行程序或shell命令、2代表系統調用、3代表庫函數調用,所以可以從標號類別,比如:
man ls 打開了ls(1),ls是shell命令
man read 打開了read(2)、read是系統調用
man fread 打開了fread(3)、fread是庫函數調用
------------------------------------------------------------------------------------------------------------------------
Q 終端是一個進程嗎
Q memory mapping segment是怎麼把顯卡,鍵盤映射上去的