作者:實作派
說到硬碟大家應該不陌生,但為什麼要做「硬碟格式化」?什麼是硬碟分割?壞軌又是什麼?就讓我來說分明吧!
硬碟的構造
如果把硬碟拆開,你會看到由碟片組成的裝置,這就是資料最後實際儲存的地方,而旁邊的三角形吊臂就是用來支撐讀寫頭的地方,讀寫頭很小,位在吊臂末端尖尖的地方,用來 read/write 資料。
硬碟資料的組織編排
在小小的碟片裡面,擠滿了密密麻麻的資料,硬碟是如何找到正確的資料位置呢?這要講到碟片上的組織了。如下圖,每個碟片都規劃了一圈圈的磁軌 Track,每一個磁軌又劃分成好幾個磁區 Sector,而磁區 Sector 就是硬碟每次讀寫的最小單位,所以硬碟並非是一個個 byte 讀寫,它是一個個 Sector 讀寫。Sector 的大小以前是 512 bytes,而現在的硬碟則是 4096 bytes。
你會發現上圖的 Sector 數量在外圈比較多,在內圈比較少,這個配置稱為 Zone Bit Recording,它可以讓碟片的空間運用得效率更好,現在的硬碟幾乎都是採用這種方式。早期的硬碟無論內外圈,全部就像切披薩一樣,整個扇形區域都是一個sector,這樣會造成碟片的使用效率低落,因為外圈的圓周比較長,資料密度較低,而 Zone Bit Recording 可以解決這個問題。
在 Linux 系統內,硬碟裝置被歸類為 Block device,這裡所謂的 Block 並非指硬碟的外型看起來像磚塊,而是指硬碟每次讀寫都必須是一個個磁叢 Cluster 讀寫,那磁叢是什麼?每個 Cluster 是好幾個連續 Sector 組成的,看起來就像是一塊塊的讀寫,因此硬碟稱為 Block device。
另外,每個碟片有 2 面,所以需要 2 個讀寫頭。前面的硬碟照片內有 2 個碟片,也就需要 4 個讀寫頭,因為碟片的正反面都可以拿來儲存資料,基本上就是能用的空間都用上去。
所以如果要讀取硬碟資料,必須給硬碟一組類似座標的資訊,才能精準抓到資料,也就是 Track、Sector、Header。利用這三種資訊來定位資料位置的方法,稱為 CHS 定址方式,眼尖的你應該會發現 Track 與 CHS 的第一個字母 C 其實完全對不上,這是怎麼回事?這個 C 其實是磁柱 Cylinder 的意思,也就是把每個碟片上相同位置的 Track 疊起來後,想像它們是個空心圓柱,因此稱為 Cylinder,不管是 Track 還是 Cylinder 他們想表達的都是同一個意思。
類似的名稱定義問題也發生在磁區 Sector。我畫的 Sector 是用來表達資料存取的最小單位,但有些圖會把 Sector 畫成像切蛋糕一樣的扇形圖,它們要表達的是扇區 Sector,因為這是用來定位的依據。所以這些名詞知道就好,不用太拘泥。
現今 CHS 定址方式只用在硬碟內部,對外的話硬碟控制器都採用 LBA(Logical Block Addressing)定址,也就是把磁區從 0 開始編號,每次加 1 直到最後一個磁區為止,一般會寫為 LBA 0、LBA 1、LBA 10440 之類的,以此類推。
LBA 與 CHS 的換算就由硬碟控制器來處理,這樣作業系統就不用額外操心這一塊,操作起來會比較方便。早期的電腦沒有LBA 定址,加上每顆硬碟的 CHS 都不太一樣,所以每換一顆硬碟都必須在 BIOS 裡面設定 CHS 參數,實在有夠麻煩,後來有了 LBA 之後就方便多了。
磁區如何定址
前面寫得長篇大論,問題是當你實際拿到碟盤,馬達開始旋轉後,到底哪裡是 LBA 0?哪裡是 LBA 1 呢?碟片上光禿禿的也沒有任何物理性的記號用來標示 Sector number,硬碟是怎麼做到辨認磁區號碼的?
原來每個磁區除了放 user 的資料外,還存放了一些控制資訊,如下圖,每個磁區的最開頭都會有特定的 0,1 交替形式,稱為 Premable,用來告訴硬碟有個磁區要來了,於是硬碟便開始等待同步訊號 Sync 發生,一旦收到同步訊號之後,緊接著就是要知道這個讀到的磁區到底是哪個位址 Addess mark,用來判斷這個位址是否為我們要的。
接著後面的資料 Data 才是我們要的硬碟資料,之後接著有 ECC(Error Control Coding),它是由前面的資料 Data 所計算出來的特殊值,若 Data 有損壞,算出來的 ECC 一定不會跟原本的相同,因此可以透過 ECC 得知 Data 哪裡有錯並且修復。
磁區的最後會留一小段空白 Gap,那是給磁頭的讀取電路辨認這裡已經告一段落了,同時也給系統對剛才讀寫的資料有時間做處理。
順帶一提,雖然電腦世界的資料是 0 與 1 組成,但是在磁區內的資料可不是直接把 0 與 1 轉換成磁極 S 與 N 喔!因為如果遇到連續相同的資料可能會讓磁場增大進而影響相鄰的磁區,所以實際寫在碟盤上的資料是編碼過的資料,才會有以前的 MFM(Modified Frequency Modulation)硬碟,一直到後來的 PRML(Partial Response Maximum Likehood)處理方式,這部分各位知道就好,再往下鑽就是通訊編碼的領域了。
硬碟從哪裡開始讀?
對於作業系統來說,硬碟就像是一張畫好格子的稿紙,不管你用的作業系統是 Windows、Linux 還是 Apple,這張稿紙的一個格子就是一個 Sector,或者說一個 Block,至於格子裡面要填什麼東西,大家就各憑本事,於是才有各式各樣的檔案系統File System 出現,例如 Windows 有 FAT/FAT32/NTFS、Linux 有 EXT2/EXT3/EXT4、Apple 有 APFS,這些檔案系統的頭幾個 Block 記載著硬碟資料結構的重要資訊,目前常見的結構有兩種分別是 MBR 與 GPT,說明如下。
MBR
所有的 File system,一定需要有個地方用來敘述整顆硬碟的資料結構,例如哪個區段當作 C 槽、哪個區段是 D 槽,也就是硬碟分割表 Partition table。如下圖,這個用來記錄硬碟資料結構的內容稱為 MBR(Master Boot Record),它固定放在硬碟的 Sector 0,MBR 當中允許 user 最多規劃 4 個 Partition。
一定有人會說,我硬碟分了 5 個 partition 甚至更多,看起來並沒有限制啊。這是因為如果要再多一些 Partition 的話,會使用延伸分割 Extension partition,也就是把最後一個 Partition 內部再分好幾個邏輯分割 Logical partition,這樣的話以 MBR 的角度來看,就仍然是 4 個 partition,以作業系統的角度來看,就會有 4 個以上的 partition,這些多出來的 Logical Partition 要如何對應到實際的 Partition,就必須由作業系統來轉換。
GPT
隨著時代改變,MBR 的 4 個 Partition 已經不太夠用,於是有了 GPT 這種新規格出來,它最多能使用 128 個Partition,而且為了不讓 user 的衝擊太劇烈,它還把 LBA 0 繼續保留給傳統的 MBR 使用,這樣就有與過去相容的效果。
如此一來,大家就可以在一台電腦上安裝多個作業系統,若是做系統測試的人應該很有需要吧!各種版本的Windows/Linux 全部要裝過一次才能方便測試,有了 GPT 確實是很方便,當然它還有其他優點,就不在這裡寫了。
硬碟格式化
有了硬碟分割的 Partition 規劃之後,就可以依照每種 File system 所需要的格式,依各種規劃的數值填入 Partition table內,以後系統才知道要去哪些 LBA 抓資料,這個佈局的動作就稱為格式化。
現代人講求效率,所以 Windows 的格式化還分成完整與快速兩種:
快速格式化
只把分割區 Partition 內的空間部分覆寫,例如 File system 標頭,以及其它相關的必要設置,之前已存在的資料區通通不動它,等同於遺失的資料,但是其實資料還在某個地方。
完整格式化
除了 File system 的標頭之外,也會把分割區其餘空間填上 0x00,所以之前的資料會被 0x00 蓋掉,資料完全消失,缺點就是耗時間,容量大的硬碟可能會耗上 20 小時。
完整格式化 vs. 快速格式化
我做了一個實驗,用來測試兩種格式化的差別,下圖是我用舊硬碟重新分割出 50 MB 空間當作 E 槽用來做實驗,並建立一個 68 KB 大小的檔案 1.txt,而且為了之後方便尋找,我在這個檔案的開頭填上一個獨一無二的關鍵字作為標記「wiki test」,雖然它是這個 E 槽的第一個檔案,也是唯一一個檔案,但檔案實體卻不一定在 Partition 最前面的 LBA,所以我才把 E 槽規劃為小小的 50 MB,不然動輒 300 GB 的分割區找起來簡直是大海撈針。
我使用是網路上找到的叫做 HxD 的工具,它可以開啟整顆硬碟、分割區、檔案,可以看到每個 Sector(LBA)的資料。
快速格式化
首先在 E 槽的分割區內找到我們的「wiki test」關鍵字,用來確認檔案內容在哪個相對磁區,如下圖這個檔案起始位址在Sector 32736。
然後先進行快速格式化,接著把檔案管理員打開,確認裡面都沒有檔案了,然後把 E 槽的內容按 F5 更新,你會發現 Sector 32736 的內容完全沒變。
雖然已經格式化了,但由於採用快速格式化的關係,因為檔案指標已經消失,所以找不到檔案,但實際的內容都還在原來的地方。基本上 Delete 檔案,甚至從資源回收桶清除,也並非真的把資料報銷,原理跟前面講的一樣。
如果有心人硬是一個個 Sector 的找資料,要把你 Quick format 之後的硬碟資料取出,是絕對有可能的,之前的陳冠希裸照事件就是一個血淋淋的例子。
完整格式化
再來則執行完整格式化,由於只有 50 MB 的分割區,速度還滿快的。如下圖,完整格式化之後,檔案依舊不存在 File system 內,但你會發現在相同的磁區內,剛剛的資料全部消失,它全部被 0x00 覆寫過去了。所以要避免資料外流,或有安全疑慮的硬碟要報廢之前最好能先做過 Full format,才能保證資料已經銷毀。
完整格式化另外的好處則是,它會幫你檢查是否有壞軌。
配置單位大小
Windows 格式化選單內有個配置單位大小選項,這個是磁叢 Cluster 的大小,它是作業系統最小的讀寫單位。實際上一個Cluster 是由 2n 個 Sector 所組成的,作業系統只看得到 Cluster,在 Linux 系統裡稱為 Block,底層硬碟真正在讀寫的仍以 Sector 為單位。
如果要知道自己的硬碟每個 Sector 是多大,可以在管理員權限之下使用 fsutil fsinfo ntfsinfo 看到相關資訊。儘管實體硬碟每個磁區 Sector 是 4096 bytes,作業系統看到的磁區(Logical Sector)仍然假裝是 512 bytes,這當然是歷史共業,為了相容所採用的權宜之計。
早期硬碟每個 Sector 是 512 bytes,後來則出現更大的 4096 bytes 磁區,因為這樣碟片使用的效率較高,這種格式稱為Advanced Format(AF)。檔案系統為了因應這種改變,但又不能讓使用者感覺變化太多,只好弄了一個 Logical Sector 給使用者看。在這個例子內,一個 Cluster 則是 8 個 Sector,也就是 4096 bytes。
我猜想如果硬碟是 AF 格式,每 Sector 是 4096 bytes,系統的 Logical Sector 也設定成 4096 bytes,效率應該會好一些吧,這部分我沒做過實驗。
壞軌 Bad Sector
所謂壞軌 Bad sector 其實應該稱為壞磁區,也稱為 Bad block,只要硬碟的 Data 與 ECC 不吻合,或著說讀取的資料有錯誤時,就會被判定為壞軌 Bad Sector。
Reallocated Sector Count – SMART item 5
一旦出現壞軌,硬碟就會自動把備用的好軌拿來用,user 完全不會感受到壞軌的存在,一切都如往昔,但硬碟會在自己的 SMART report 的 item 5 上記上一筆,下圖是給各位參考用,我的硬碟還沒有壞軌出現,目前原始資料為 0,若有 1 個壞軌出現,原始資料會+1,「最差值」會開始下降。
SMART 的「值」有點像考試分數一樣,有些總分 100 有些是 200,總之分數越高越好,萬一分數太低,低過界限所定義的值,那表示你的硬碟病入膏肓了,所以通常在逼近界限值的時候就該換硬碟了。
Current Pending Sector – SMART item 197
有些磁區讀寫不穩定,一旦讀寫成功便會馬上以備用磁區來替換,如果這些有問題的磁區能找得到備用的磁區做替換,那麼剛才講的 Reallocated sector count 就會+1,如果備用磁區用完了,或是其它原因讓替換工作失敗,那等於有問題的磁區就會一直處於等待 Reallocated 的情況,此時 Current pending sector 這一項就會被 +1,想當然爾這個項目比 item 5 嚴重得多,因為儲存的資料有錯誤,又找不到備用磁區替換。
出廠就有壞軌
事實上壞軌有兩種,一種是天生的,一種是後天的。
現在硬碟容量這麼大動輒 300 GB 起跳,想要求硬碟內部零壞軌那真的是太苛求了,硬碟出廠時一定會做一次掃描,用來偵測壞軌,偵測到的壞軌會記錄在一個稱為 P-List(Primary defect table)的清單內,這樣使用者就不會踩雷,這就是天生的壞軌。
但消費者買回家後,一定也會有些本來就快要掛掉的磁區,經過長期使用之下就真的變成壞軌了,這些就是後天的壞軌,硬碟會把這些壞軌記錄在自己的 G-List(Growth defect table)清單內,這樣將來使用的時候就可以避掉壞軌,而不會踩雷。
一旦有壞軌,它就是壞軌了,也許是該區的磁力便小,也許真的有刮傷,總之不會有甚麼工具程式可以修好它,我也想不出可以如何修復壞軌。
硬碟失效是一個漸進的過程,你需要根據自己的需求來決定怎麼看待 SMART,並不是 SMART 的分數只要有下降,就一定要趕快花錢買硬碟,它只是一個硬碟的健康指數而已,要不要換硬碟就看自己的需求在哪裡。
低階格式化
還記得前面講每個磁區都有 preamble/sync/addr/data/ecc 這些區段吧,所謂低階格式化就是在一片剛做好的碟片上,把這些資料結構放到碟片上,講得白話些就是在硬碟的盤子上畫格子。
在早期還有軟碟片 Floppy disk 的時代,當時在軟碟上要做格式化就是需要從建立 sector 開始,這種就是低階格式化。在當時的時空背景下,所有的 format 動作都是土法煉鋼一鏡到底,沒有什麼快速格式化,只要做完 format 你的碟片絕對是乾乾淨淨。
當時如果要在硬碟上做低階格式化,都會被警告說很傷硬碟種種之類的話語,時至今日仍然還有號稱 Low Level Format 的程式存在,但其實它已經不是做畫格子的事情了,因為在與硬碟的溝通語言 ATAPI 裡面已經沒有這項指令了,現在看到的Low Level Format 程式其實只是把 0x00 的「資料」填到每個磁區裡而已。
所以現在的 LLF 已經與以前的 LLF 不一樣了,正確來說不能稱為 Low Level Format,應該稱為 Zero-filling。
硬碟的前置作業
一顆硬碟要能上線使用,需要先做分割規劃,分割程式會自動根據我們的設定把 MBR 或是 GPT 填好,有了 Partition 劃分之後,每個 Partition 就能依照不同的檔案系統做格式化,格式化之後系統就能認到 File system,就可以開始存檔使用了。