Linux 磁盤中的文件

1.磁盤結構

Linux中的文件加載到內存上之前是放到哪的?
放在磁盤上的文件——>訪問文件,打開它——>找到這個文件——>路徑
但文件是怎樣存儲在磁盤上的

1.1物理結構

在這里插入圖片描述
磁盤可以理解為上百億個小磁鐵(如N為1,S為0)
清除磁盤數據:消磁——軟件、物理、化學

1.1.1磁盤的存儲結構

在這里插入圖片描述
扇區:是磁盤存儲的基本單位,512字節,塊設備
磁頭在擺動的本質:定位磁道(柱面)
磁盤盤片旋轉的本質:定位扇區
磁盤容量 = 磁頭數* 磁道數 * 扇區數 * 每扇區字節數

如何定位一個扇區?
1.先定位磁頭(Header)
2.確定磁頭要訪問哪一個柱面(磁道)(Cylinder)
3.定位一個扇區(Sector)
4.這就是CHS地址定位法

在這里插入圖片描述

1.2邏輯結構

1.2.1邏輯抽象

?個細節:傳動臂上的磁頭是共進退的
柱?是?個邏輯上的概念,其實就是每??上,相同半徑的磁道邏輯上構成柱?。
所以,磁盤物理上分了很多?,但是在我們看來,邏輯上,磁盤整體是由“柱?”卷起來的。

磁道:
某?盤?的某?個磁道展開
在這里插入圖片描述
柱?:
整個磁盤所有盤?的同?個磁道,即柱?展開:即二維數組

在這里插入圖片描述
整盤:
整個磁盤不就是多張?維的扇區數組表(三維數組?)

在這里插入圖片描述
每?個扇區都有?個下標,我們叫做LBA(Logical Block Address)地址,其實就是線性地址。

1.2.2CHS轉LBA

LBA,1000,CHS 必須要! LBA地址轉成CHS地址,CHS如何轉換成為LBA地址?
由硬盤自己來做!固件(硬件電路,伺服系統)

CHS轉成LBA:
? 磁頭數每磁道扇區數 = 單個柱?的扇區總數
? LBA = 柱面號C * 單個柱面的扇區總數 + 磁頭號H * 每磁道扇區數 + 扇區號S - 1
LBA轉成CHS:
? 柱?號C = LBA // (磁頭數
每磁道扇區數)【就是單個柱面的扇區總數】
? 磁頭號H = (LBA % (磁頭數*每磁道扇區數)) // 每磁道扇區數
? 扇區號S = (LBA % 每磁道扇區數) + 1
? “//”: 表示除取整

2.抽象理解分區,格式化

OS和磁盤進行IO的時候,以扇區為基本單位,512字節作為單次數據量,有些少。
以1KB、2KB、4KB、8KB為單位,一般以4KB數據塊——8個扇區
即一個數據庫——8個LBA地址,這樣就將磁盤轉化成了 以塊為單位的一維數組

通過將磁盤分區、分組,使用分治實現管理整個磁盤
在這里插入圖片描述

3.Ext系列的文件系統,inode號和inode

知識點:
1.文件 = 內容+屬性
2.屬性也是數據,以結構體方式構建出來的inode
3.一個文件一個inode,inode是屬性數據的集合

在Linux中可以使用ls -l -i命令來查看文件inode編號,找到inode就能映射到對應儲存位置Data

在這里插入圖片描述

  • Block Group:ext2 文件系統會根據分區的大小劃分為數個 Block Group。而每個 Block Group都有著相同的結構組成。
  • 超級塊(Super Block):存放文件系統本身的結構信息,管理整個分區,不是每個組的super bloc都起作用。記錄的信息主要有:bolck 和inode 的總量,未使用的 block 和 inode 的數量,一個 block 和 inode的大小,最近一次掛載的時間,最近一次寫入數據的時間,最近一次檢驗磁盤的時間等其他文件系統的相關信息。
  • GDT,Group Descriptor Table:塊組描述符,描述塊組屬性信息
  • 塊位圖(Block Bitmap):Block Bitmap 中記錄著 Data Block中哪個數據塊已經被占用,哪個數據塊沒有被占用
  • inode 位圖(inode Bitmap):每個 bit 表示一個 inode 是否空閑可用
  • 節點表(inode table):存放文件屬性 如文件大小,所有者,最近修改時間等 ,如下圖inode邏輯結構
  • 數據區(data blocks):存放文件內容
    在這里插入圖片描述

刪除的本質是設置inode bitmap、block bitmap,設置對應inode 、block無效
格式化:對inod bitmap、block bitmap 、GDT 、super block操作

4.理解什么叫文件,什么叫目錄,準確理解文件系統

格式化即寫入空的文件系統

GDT中存有start_inode、start_block他們是這個組包含的inode、block的起始編號。
在這里插入圖片描述
inode號的個數、block的個數都是固定的!(先分配inode、再分配block,故不存在inode沒用完、data block用完的情況)

關于inode
1.inode以分區為單位,一套inode
2.inode分配時,只需確定起始inode即可
關于block
1.塊號也是以分區為單位統一編號的

那么如何分配一個inode、block?
inode、block都是全局的(整個分區通用的),先根據GDT中的起始編號確定組,再根據bitmap確定是否有效,再通過inode table找到inode屬性集

4.1文件的增刪查改流程

已知inode號
1.如何查找一個文件?

  • 通過GDT找到分組,使用inode號 - start_inode,找到組內的位置,通過bitmap判斷該位置是否有效,再通過inode table找到inode屬性集。

2.如何刪除

  • 找到文件后設置bitmap

3.如何新增
4.如何修改

  • 找到文件后對inode、data block進行修改

4.2子問題1:inode和block怎么映射的

將組的設計和文件內容的設計解耦了,文件的內容可以是其他組的塊
在這里插入圖片描述

4.3子問題2:

4.3.1.我們使用中使用的都是文件名,OS怎么拿到inode的

文件名不再inode中保存。存在哪?——文件名分為:普通文件、目錄文件——存在自己所處目錄的數據塊中

4.3.2.如何理解目錄文件

目錄 = inode + data block = 屬性 + 內容
內容:對應數據塊存儲了 文件名:inode的映射關系。因為同一個目錄中不能有同名文件,所以inode和文件名互為映射。

為什么要這樣設計?
因為文件名可長可短,inode是數字定長,OS管理時效率高。

命令ls -ln-ln可以將能顯示成數字的內容顯示為數字

查找文件的邏輯:
找到文件名——>打開當前目錄——>當前目錄也是文件,找到inode編號——>逆向路徑解析——>從根目錄找回去

為什么任何一個文件,都要有路徑?? 進程提供的路徑
每個進程都要有一個CWD,故 任何目標文件都有路徑

那每次打開文件都要對路徑進行逆向解析嗎?
Linux可以對路徑結構進行緩存
Linux以多叉樹的結構對操作路徑進行緩存
在這里插入圖片描述

4.3.3.文件描述符和進程的關系

通過struct file 可以找到:
1.操作表
2.緩沖區
3.

path---dentry---inode|        |

通過文件名訪問磁盤上文件的流程:
通過task_struct找到打開的文件,通過file中的path找到dentry解析文件路徑,通過自己所在目錄的data block找到此文件的inode,再通過inode將磁盤中的內容映射到文件內核緩沖區
在這里插入圖片描述

5.分區模擬掛載

怎么確認自己在哪一個分區中?(通過路徑前綴)
多個分區——>一個分區包含若干個普通目錄
|
只有分區該分區無法直接使用
分區必須經過“掛載”到目錄上,分區才可以通過路徑的方式進行訪問

df -h可以查看磁盤信息

#復制數據
dd if=/dev/zero of=./disk.iso bs=1M count=5
#創建虛擬磁盤分區
mkfs.ext4 disk.iso
#掛載分區
mount -t ext4 ./disk.iso /mnt/myvda# #卸載分區
#umount 

任何一個分區,天然有基本路徑(經過掛載,路徑+掛載點+新建目錄)

6.軟硬鏈接

ln -s file.txt file-soft.link	#軟鏈接
ln file.txt file-hard.ling #硬鏈接

6.1如何理解軟硬鏈接

軟鏈接本質是一個獨立的文件,硬鏈接本質不是一個獨立的文件
a.軟鏈接沒有獨立的inode,軟鏈接內容上,保存的是文件的路徑,類似Windows的快捷方式
b.硬鏈接本質就是一組文件名和已經存在的文件的映射

6.2為什么要用軟硬鏈接?各種應用場景

軟鏈接:快捷方式(幫助快速找到指令和庫)
硬鏈接:

  • 1.可以使用硬鏈接對文件進行備份
  • 2.硬鏈接文件后,因為inode相同,OS會存儲inode的引用計數,目錄也有引用計數,可通過硬鏈接分析一個目錄內含幾個目錄(結合3.)
    在這里插入圖片描述
  • 3.Linux不允許對目錄進行新建硬鏈接(… 和 . 被特殊處理了)(因為會形成環狀路徑,軟鏈接也會形成環狀路徑,但軟鏈接的文件類型標識為l)

7.動態庫和靜態庫

7.1靜態庫

制作靜態庫

# lib為固定前綴,.a為固定后綴 -rc:r意為replace,c意為create
ar -rc libmylib.a file1.o file2.o file3.o

使用靜態庫
方法一:安裝到系統中 一般為目錄 /lib64

# 使用-l選項:指定名稱的外部庫,庫名稱去前綴、后綴
gcc main.c -lmystdio

方法二:和源文件在同一目錄下

# -L選項告訴編譯器,編譯的時候查找庫時,除了系統路徑,也要在指明路徑下找
gcc main.c -L. -lmystdio

gcc在查找靜態(動態)庫時,不會在當前路徑下找
方法三:使用帶路徑的庫

# -I指定路徑頭文件 -L指定鏈接的目錄 -l指定鏈接哪個庫的目錄
gcc main.c -Istdc/include -Lstdc/lib -lmystdio

7.2動態庫

動態庫制作:

# -shared :不要形成可執行程序,形成.so庫
gcc -shared# -fPIC:意為 flag position ignore code
# 此指令為在.c文件編譯為.o文件時形成與位置無關碼
gcc -fPIC

動態庫的使用
方法一:安裝到系統 /lib64庫中,鏈接方式與靜態庫相同

# 此命令可以查看依賴庫
ldd a.out 

方法二:和源文件在同一目錄下(與靜態庫相同,gcc查找動態庫時不會在當前路徑下查)
方法三:使用帶路徑的庫(與靜態庫相同)

7.3知識點

鏈接動態庫的程序執行程序時會顯示找不到.so庫
在這里插入圖片描述

編譯時找動態庫是告訴編譯器庫在哪
運行時呢?OS要加載程序,系統找不到庫——靜態庫需要找嗎?不需要

如何給系統指定路徑,查找自己的動態庫
1*.拷貝到系統默認路徑下,如/lib64
2.在系統路徑,建立軟鏈接 ln
3*.Linux系統中,OS查找動態庫,修改環境變量:LD_LIBRARY_PATH(將庫路徑加入環境變量)
4.idconfig(更改系統配置文件)配置如 /etc/ld.so.confd/

若同時提供動 、靜態庫,gcc、g++默認使用動態庫,-static指明靜態鏈接
如果強制靜態鏈接,必須提供對應靜態庫
如果只提供靜態庫,但鏈接方式是動態鏈接的,gcc、g++沒得選只能針對你的.a局部性采用靜態鏈接

7.4動態庫的理解,動態庫的加載,進程地址空間

a.原理上理解動態庫(共享庫)
將動態庫映射到進程的虛擬地址空間(共享區)
進程執行庫方法時,是在自己的地址空間中跳轉執行的
在這里插入圖片描述

8.EIF文件

8.1可執行程序格式

-可重定位?件(Relocatable File) :.o ?件。
-可執行文件(Executable File) :即可執行程序。
-共享目標文件(Shared Object File) :即 xxx.so文件
上面三種文件都屬于EIF文件,EIF文件的結構如下:
在這里插入圖片描述
section中就是一段一段文件的內容,如:代碼區(.text)、數據區(.data)
鏈接:就是將EIF文件一段一段相同屬性的section進行合并。
在這里插入圖片描述

對于任何文件,文件的內容就是一個巨大的一維數組
標識文件任何一個區域,可以使用 偏移量+大小的方式
readelf指令可以查看某個EIF文件結構

8.2地址空間——可執行程序的加載

操作系統是要認識可執行程序的,那操作系統如何管理可執行程序的的代碼的。
提出以下兩個問題

1.mm_struct中的屬性由誰初始化的?
2.可執行程序有沒有地址的存在?

8.2.1可執行程序的地址

readelf -S 或 --section -headers #顯示EIF文家節頭信息

查看EIF文件節頭信息,發現每一段匯編代碼、函數頭都有一個地址。
在這里插入圖片描述
當代OS的可執行程序編址模式:
平坦模式:
邏輯地址 = 起始地址 + 偏移量[000···,FFF···]
故可以看出,EIF在沒有加載到內存時,已經按照[000···,FFF···]進行編址了(虛擬地址)

故編譯器編譯時,就已經形成虛擬地址了。

邏輯地址(磁盤EIF) == 虛擬地址(加載到內存中時) //故邏輯地址和虛擬地址只是兩種不同情景下的表達

執行程序時使用的是虛擬地址,執行時將Entry Point address放入PC指針,由MMU硬件(Memory Management Unit,查表邏輯在硬件電路中實現)查頁表將虛擬地址轉換為物理地址

  • 故CPU出來的都是物理地址
  • CR3寄存器,指向頁表的起始地址

所以,虛擬地址是操作系統、CPU、編譯器共同協作下的產物!!!

為什么要有虛擬地址和虛擬地址空間?
將編譯器與OS解耦,編譯器編址就可以以平坦模式編址了

8.2.2mm_struct中的屬性填充

mm_struct存在一條屬性mmap為分區鏈表
在這里插入圖片描述

srtuct vm_area_struct即為虛擬地址的分區屬性,其中包含vm_start和vm_end記錄了開始和結束的地址。
在這里插入圖片描述
鏈接動態庫到共享區,即新建vm_area_struct結構體鏈入鏈表
在這里插入圖片描述

8.3動態庫加載的理解

我們的程序運行之前,先把所有庫加載并映射,所有庫的起始虛擬地址都應該提前知道
然后對我們加載到內存中的程序的庫函數調用進行地址修改,在內存中二次完成地址設置
(加載地址重定位)
在這里插入圖片描述
然而,代碼區(.text)不是編譯完成后就不能修改了嗎,每次執行時動態庫的虛擬地址 = 基地址 + 偏移量,不是要修改嗎?
所以:動態鏈接采用的做法是在.data(可執行程序或者庫自己)中專門預留一片區域用來存放函數
的跳轉地址,它也被叫做全局偏移表.GOT(Global Offset Table),表中每一項都是本運行模塊要引用的一個全局變量或函數的地址。代碼區調用的動態庫函數會指向此表。

所以:GOT + 庫方法偏移量,這兩種解決方案實現了與地址無關

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917928.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917928.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917928.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【方法】Git本地倉庫的文件夾不顯示紅色感嘆號、綠色對號等圖標

文章目錄前言開始操作winr,輸入regedit,打開注冊表重啟資源管理器前言 這個綠色對號圖標表示本地倉庫和遠程的GitHub倉庫內容保持一致,紅色則是相反咯,給你們瞅一下。 首先這兩個東西你一定要安裝配置好了,安裝順序不…

量化交易與主觀交易:哪種方式更勝一籌?

文章概要 在投資的世界里,量化交易和主觀交易如同冰與火,各自擁有獨特的優勢與挑戰。作為一名投資者,了解這兩種交易方式的差異和各自的優缺點至關重要。本文將從決策依據、執行方式、風險管理等方面深入探討量化交易的精確性與主觀交易的靈活…

【JS】扁平樹數據轉為樹結構

扁平數據轉為最終效果[{"label":"疼遜有限公司","code":"1212","disabled":false,"parentId":"none","children":[{"label":"財務部","code":"34343&quo…

數據結構4-棧、隊列

摘要:本文系統介紹了棧和隊列兩種基礎數據結構。棧采用"先進后出"原則,分為順序棧和鏈式棧,詳細說明了壓棧、出棧等基本操作及其實現方法。隊列遵循"先進先出"規則,同樣分為順序隊列和鏈式隊列,重…

大數據spark、hasdoop 深度學習、機器學習算法的音樂平臺用戶情感分析系統設計與實現

大數據spark、hasdoop 深度學習、機器學習算法的音樂平臺用戶情感分析系統設計與實現

視頻匯聚系統EasyCVR調用設備錄像保活時視頻流不連貫問題解決方案

在使用EasyCVR過程中,有用戶反饋調用設備錄像保活功能時,出現視頻流不連貫的情況。針對這一問題,我們經過排查與測試,整理出如下解決步驟,供開發者參考:具體解決步驟1)先調用登錄接口完成鑒權確…

【保姆級喂飯教程】python基于mysql-connector-python的數據庫操作通用封裝類(連接池版)

目錄項目環境一、db_config.py二、mysql_executor.py三、test/main.py在使用mysql-connector-python連接MySQL數據庫的時候,如同Java中的jdbc一般,每條sql需要創建和刪除連接,很自然就想到寫一個抽象方法,但是找了找沒有官方標準的…

【MCP服務】藍耘元生代 | 藍耘MCP平臺來襲!DeepSeek MCP服務器玩轉大模型集成

【作者主頁】Francek Chen 【專欄介紹】???人工智能與大模型應用??? 人工智能(AI)通過算法模擬人類智能,利用機器學習、深度學習等技術驅動醫療、金融等領域的智能化。大模型是千億參數的深度神經網絡(如ChatGPT&#xff09…

Spring Boot 整合 Minio 實現高效文件存儲解決方案(本地和線上)

文章目錄前言一、配置1.配置文件:application.yml2.配置類:MinioProperties3.工具類:MinioUtil3.1 初始化方法3.2 核心功能3.3 關鍵技術點二、使用示例1.控制器類:FileController2.服務類3.效果展示總結前言 Minio 是一個高性能的…

【Unity3D實例-功能-鏡頭】第三人稱視覺-鏡頭優化

這一篇我們一起來調整一下Cinemachine的第三人稱視覺的鏡頭設置。一般用于ARPG角色扮演游戲的場景中。Unity里頭,這種視角簡直就是標配。來吧,咱們一起研究研究怎么調出這種視角效果!目錄:1.調整虛擬攝像機的Y軸2.調整虛擬攝像機的…

二叉樹算法之【中序遍歷】

目錄 LeetCode-94題 LeetCode-94題 給定一個二叉樹的根節點root&#xff0c;返回它的中序遍歷結果。 class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result new ArrayList<>();order(root, result);return res…

Android14的QS面板的加載解析

/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java QS 面板的創建 getNotificationShadeWindowView()&#xff1a;整個systemui的最頂級的視圖容器&#xff08;super_notification_shade.xml&#xff09;R.id.qs_frame &…

解鎖webpack核心技能(二):配置文件和devtool配置指南

一、配置文件webpack 提供的 cli 支持很多的參數&#xff0c;例如 --mode 。在我們平時的開發過程中&#xff0c;我們要學習很多的功能&#xff0c;這些很多都是可以用參數來完成的。那么后邊就會導致參數越來越多&#xff0c;我們使用命令特別的不方便&#xff0c;所以我們會使…

Gitlab+Jenkins+K8S+Registry 建立 CI/CD 流水線

一、前言 DevOps是一種將開發&#xff08;Development&#xff09;和運維&#xff08;Operations&#xff09;相結合的軟件開發方法論。它通過自動化和持續交付的方式&#xff0c;將軟件開發、測試和部署等環節緊密集成&#xff0c;以提高效率和產品質量。在本篇博客中&#xf…

【Linux】特效爆滿的Vim的配置方法 and make/Makefile原理

一、軟件包管理器 1、Linux下安裝軟件的常見方式&#xff1a; 1&#xff09;源代碼安裝——不推薦。 2&#xff09;rpm包安裝——不推薦。 3&#xff09;包管理器安裝——推薦 2、安裝軟件命令 # Centos$ sudo yum install -y lrzsz# Ubuntu$ sudo apt install -y lrzsz 3、卸…

Spring Boot Actuator 監控功能的簡介及禁用

Spring Boot Actuator: Production-ready Features 1. 添加依賴 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> </dependencie…

Matlab(1)

一、基本操作1. matlab四則運算規則&#xff1a;先乘除后加減&#xff0c;從左到右2、對數和指數的表示sin(pi^0.5)log(tan(1))exp&#xff08;sin&#xff08;10&#xff09;&#xff09;3、類型&#xff1a;matlab變量默認為double4、who&whos&#xff1a;命令行輸入who&…

Kotlin Android 開發腳手架封裝

Kotlin Android 開發腳手架封裝&#xff08;模塊化版本&#xff09; 我將按照模塊化設計原則&#xff0c;將腳手架拆分為多個文件&#xff0c;每個文件負責特定功能領域&#xff1a; 1. 核心初始化模塊 文件路徑: core/AppScaffold.kt object AppScaffold {lateinit var contex…

Flutter 報錯解析:No TabController for TabBar 的完整解決方案

目錄 Flutter 報錯解析&#xff1a;No TabController for TabBar 的完整解決方案 一、錯誤場景&#xff1a;當 TabBar 失去 "指揮官" 二、為什么 TabBar 必須依賴 Controller&#xff1f; 1. TabBar 與 TabController 的協作關系 2. 狀態管理的核心作用 3. 實戰…

【24】C++實戰篇——【 C++ 外部變量】 C++多個文件共用一個枚舉變量,外部變量 extern,枚舉外部變量 enum

文章目錄1 方法2 外部變量 應用2.1 普通外部全局變量2.2 枚舉外部全局變量 應用2.2.2 枚舉外部變量優化c多個文件中如何共用一個全局變量 c頭文件的使用和多個文件中如何共用一個全局變量 C共享枚舉類型給QML 1 方法 ①頭文件中 聲明外部全局變量&#xff1b; ②在頭文件對…