# Linux中的硬碟觀念 ## 磁碟盤上的資料讀寫 大家都知道傳統硬碟是透過磁頭寫在磁盤上的。 在磁盤上會進行分區,每個小區塊就是磁碟的最小物理儲存單位,稱之為磁區(sector)。磁區的物理量設計有兩種大小,分別是 512bytes(舊) 與 4Kbytes(現有)。 同一個同心圓的磁區組合成的圓就是所謂的磁軌(track)。 由於磁碟裡面可能會有多個磁碟盤,因此在所有磁碟盤上面的同一個磁軌可以組合成所謂的磁柱(cylinder)。 ![image](https://hackmd.io/_uploads/B1MYPAQGle.png) 整顆磁碟的第一個磁區特別的重要,記錄了整顆磁碟的重要資訊。 早期磁碟第一個磁區裡面含有的重要資訊我們稱為MBR(Master Boot Record)格式。 近期則因為磁碟大小增加,改為使用 GPT(GUID partition table)格式。 ## Linux中的硬體裝置 在Linux系統中,每個裝置都被當成一個檔案來對待。以下是Linux中裝置對應的檔案路徑: | 裝置 | 路徑 | | ------------------- | ------------------------------------------------------------------------------------- | | SCSI/SATA/USB硬碟機 | /dev/sd[a-p] | | USB快閃碟 | /dev/sd[a-p] (與SATA相同) | | VirtI/O界面 | /dev/vd[a-p] (用於虛擬機器內) | | 軟碟機 | /dev/fd[0-1] | | 印表機 | /dev/lp[0-2] (25針印表機)<br>/dev/usb/lp[0-15] (USB 介面) | | 滑鼠 | /dev/input/mouse[0-15] (通用)<br>/dev/psaux (PS/2界面)<br>/dev/mouse (當前滑鼠) | | CDROM/DVDROM | /dev/scd[0-1] (通用)<br>/dev/sr[0-1] (通用,CentOS 較常見)<br>/dev/cdrom (當前 CDROM) | | 磁帶機 | /dev/ht0 (IDE 界面)<br>/dev/st0 (SATA/SCSI界面)<br>/dev/tape (當前磁帶) | | IDE硬碟機 | /dev/hd[a-d]<br>(舊式系統才有,新式通常會模擬為被模擬成 /dev/sd[a-p]) | ## 磁碟分割 如果未經過分割,磁碟只是一個物理上的鐵片而已。要經過分割才能產生物理與資訊上的對應關係,讓OS理解。 ### MSDOS(MBR) MSDOS磁碟分割是IBM公司在1983年提出,最大支援容量為2.1TB。 每個磁區為512bytes,並且以一個磁柱為最小區間單位。 第一個磁區 512bytes 會有這兩個資料: * MBR(主要開機記錄區): 446 bytes,用於安裝開機管理程式 * partition table(分割表): 64 bytes,記錄整顆硬碟分割的狀態 由於partition table僅有64 bytes容量,因此最多只能分為四組紀錄區(8bytes addr*2開始與結束*4組),每組記錄區記錄了該區段的啟始與結束的磁柱號碼。這四個分割的記錄被稱為主要(Primary)分割。 記錄下來的資訊會像這樣,可以還原出每個區間的起始與結束。 ![image](https://hackmd.io/_uploads/HJxl2kyEGll.png) 而區間則會在linux中以數字表示,以上圖為例,分為4個區間,/dev/sda就會再被分為4個,分別為: | 分割 | Linux路徑 | | ---- | --------- | | P1 | /dev/sda1 | | P2 | /dev/sda2 | | P3 | /dev/sda3 | | P4 | /dev/sda4 | 然而只有四個分區不夠使用,因此有了延伸分割(Extended),將分割表最後指向的位置,使用磁區新建一個延伸分割記錄區,紀錄該磁區中的分割。 ![image](https://hackmd.io/_uploads/HyH_yg4fel.png) 因此每個硬碟最多可以有3個主要分割+1個延伸分割(因為要拿一個MBR的Primary指向Extended) 而延伸分割則會從編號5開始(1~4是留給Primary用)。因此上圖的分割會變成: | 分割 | Linux路徑 | | ---- | --------- | | P1 | /dev/sda1 | | P2 | /dev/sda2 | | L1 | /dev/sda5 | | L2 | /dev/sda6 | | L3 | /dev/sda7 | | L4 | /dev/sda8 | | L5 | /dev/sda9 | ### GPT(GUID partition table) 使用Logical Block Address(LBA,輯區塊位址)來做為分割的基本單位。預設LBA大小為512bytes,由0開始編號。 使用了LBA 0~33共34個LBA來紀錄分割資訊,整塊磁碟的最後33個LBA也拿來作為另一個備份。 整體硬碟架構變成這樣子 ![image](https://hackmd.io/_uploads/BJLiEx4zlg.png) 各LBA固定的定義如下: * LBA0 (MBR 相容區塊) 與MBR模式相似,這個相容區塊也分為兩個部份。一個就是跟之前 446 bytes 相似的區塊,儲存了第一階段的開機管理程式。而在原本的分割表紀錄區內,僅放入一個特殊標誌的分割,用來表示此磁碟為 GPT 格式。而不懂 GPT 分割表的磁碟管理程式, 就不會認識這顆磁碟。 * LBA1 (GPT 表頭紀錄) 這個部份紀錄了分割表本身的位置與大小,同時紀錄了備份用的 GPT 分割 (就是前面談到的在最後 34 個 LBA 區塊) 放置的位置, 同時放置了分割表的檢驗機制碼 (CRC32),作業系統可以根據這個檢驗碼來判斷 GPT 是否正確。若有錯誤,還可以透過這個紀錄區來取得備份的 GPT(磁碟最後的那個備份區塊) 來恢復 GPT 的正常運作! * LBA2~33 (實際紀錄分割資訊處) 從 LBA2 區塊開始,每個 LBA 都可以紀錄 4 筆分割紀錄,所以在預設的情況下,總共可以有 4\*32 = 128 筆分割紀錄 因為每個 LBA 有 512bytes,因此每筆紀錄用到 128 bytes 的空間,除了每筆紀錄所需要的識別碼與相關的紀錄之外,GPT 在每筆紀錄中分別提供了 64bits 來記載開始/結束的磁區號碼,因此,GPT 分割表對於單一分割槽來說, 他的最大容量限制就會在『 264 \* 512bytes = 263 \* 1Kbytes = 233\*TB = 8 ZB 』,要注意 1ZB = 230TB ## 開機時的硬碟操作 上面介紹完了主要分割,因此我們可以知道在開機時BIOS會先讀取MBR中的開機管理程式。而這個446bytes的管理程式也可以指向另一個磁碟分區,讓另一個磁碟分區進行管理。 ![image](https://hackmd.io/_uploads/BJBSNXVflx.png) 上圖為MBR的開機流程,可以看到透過MBR可以找到相關聯的boot sector(開機磁區)。 但BIOS為16bit,無法處理GPT。因此誕生UEFI,運行方式與BIOS完全不同。但是開機讀取的邏輯都是相同的,透過MBR去尋找相對應的boot sector完成開機。之後UEFI就會結束,完全交由OS管理硬體。 ## 分區mount與file system關係 Linux中的所有資料都是以檔案的形態來呈現的,稱為目錄樹架構(directory tree)。而根目錄`/`則是一切檔案的起點,會從根目錄開始向下尋找檔案。 ![image](https://hackmd.io/_uploads/rJFDRrNGex.png) mount可以當作是將mount的目錄設為跳轉點,直接跳轉到指定的硬碟分割槽。 ![image](https://hackmd.io/_uploads/ryS6RrVzll.png) ## Linux中對硬碟檢視的實際操作與工具 ### fdisk 針對使用MBR分割格式的硬碟進行操作,但現在新的Linux中fdisk也支援GPT分割。 列出所有磁碟與分割資訊 ```bash fdisk -l ``` 編輯特定磁碟的分割表,接下來會進入互動頁面,用m可顯示幫助 ```bash fdisk /dev/<磁碟> ``` eg: `sudo fdisk /dev/sda` ![{D94EBC3F-C969-41CE-AA11-2C47696D31ED}](https://hackmd.io/_uploads/rkGt6mBGgg.png) 互動介面中常用的命令 | 常用命令 | 功能 | | --- | --- | | p | 列出目前分割規劃 | | n | 建立新分割 | | d | 刪除分割 | | w | 寫入變更 | | q | 不儲存退出 | 互動介面任何的改變(如刪除/新增 partition)等動作都只是在RAM中操作,就算操作錯誤也不會誤刪硬碟資料,覺得操作有誤隨時都可按`q`退出,除非按`w`寫入硬碟。所以按`w`前建議按`p`印出所規劃的partition再確認 。 ### parted 較新的分割工具。 > [!Warning]parted的操作會立即生效 > 與fdisk不同的是parted的操作會立即生效,因此請確認不要誤操作。 進入parted工具,接下來會進入互動頁面,用help可顯示幫助 ```bash parted ``` 或是可以直接編輯特定磁碟的分割表 ```bash parted /dev/<磁碟> ``` eg: `sudo parted /dev/sda` ![{0C03248A-69B1-4AF3-99D4-1C16EC5283E4}](https://hackmd.io/_uploads/ryfZb4rzxg.png) ### gparted(GUI版本的parted) 圖形化介面方便操作。 ![image](https://hackmd.io/_uploads/BJkTEVHfxl.png) ### lsblk list block,列出系統的可用 Block Device,包含硬碟、USB、DVD-ROM等,但RAM disk不會列出來。 lsblk 執行預設會以樹狀列出所有 Block Device ```bash lsblk ``` ![{1FA96635-1217-4B15-ADB4-1A65597307A1}](https://hackmd.io/_uploads/HJNQ84rGle.png) lsblk 預設不會列出 empty device, 加上 -a 會列出所有 device ```bash lsblk -a ``` ![{1863CEA3-5963-411C-BEAC-B4293DBA1D46}](https://hackmd.io/_uploads/BkD48EHzeg.png) 欄位說明: | 欄位 | 內容 | | --- | --- | | NAME | block device名稱 | | MAJ:MIN | 显示主要和次要设备号。 | | RM | 是否為可移动裝置。 | | SIZE | 本栏列出设备的容量大小信息。 | | RO | 该项表明设备是否为只读。 | | TYPE | 本栏显示块设备是否是磁盘或磁盘上的一个分区 | | MOUNTPOINT | 本栏指出设备挂载的挂载点。 | ## 參考資料 [鳥哥私房菜-第零章、計算機概論](https://linux.vbird.org/linux_basic/centos7/0105computers.php) [鳥哥私房菜-第二章、主機規劃與磁碟分割](https://linux.vbird.org/linux_basic/centos7/0130designlinux.php) [鳥哥私房菜-第七章、Linux 磁碟與檔案系統管理](https://linux.vbird.org/linux_basic/centos7/0105computers.php) [海洋之星科技-fdisk指令](https://www.hy-star.com.tw/tech/linux/comm/fdisk.html) [替 Linux 新增硬碟(磁碟分割、格式化與掛載)](https://blog.gtwang.org/linux/linux-add-format-mount-harddisk/) [Linux 的 Parted 指令教學:建立、變更與修復磁碟分割區](https://blog.gtwang.org/linux/parted-command-to-create-resize-rescue-linux-disk-partitions/) [lsblk](https://wangchujiang.com/linux-command/c/lsblk.html) [lsblk – 檢視列出 Block Device 指令](https://www.ltsplus.com/linux/lsblk-command-linux-list-block-device)