sfidsk建立可啓動分區問題

前言

因爲工做上須要常常要爲嵌入式設備製做啓動SD卡,所以本人使用sfdisk編寫了自動分區、格式化和安裝文件的腳本。(不選擇fdisk是由於它是爲用戶交互設計的,在腳本上使用不夠方便)spa

實際使用過程當中,有同事反饋在有些機器的虛擬機上使用,製做出來的卡不能啓動。通過一番排查,終於搞清楚問題所在。設計

先從結論來講,使用sfdisk時,最好指定第一個分區的起始柱面(cylinder)爲1或以上code

基礎知識 - sfdisk使用

截選自man sfidsk :orm

sfdisk reads lines of the form
       <start> <size> <id> <bootable> <c,h,s> <c,h,s>
where each line fills one partition descriptor.

Fields are separated by whitespace, or comma or semicolon possibly followed by whitespace; When a field is absent or empty, a default value is used.

即sfdisk會從標準輸入讀取分區描述信息;每一行描述一個分區,經常使用格式爲:<起始柱面>,<柱面數量>,<分區ID>,< bootable >。若是參數沒有指定,則使用默認值;而<起始柱面>的默認值爲當前最小可用的柱面編號。ip

所以最初編寫出來的腳本相似這樣:虛擬機

DRIVE=$1
SIZE=`fdisk -l $DRIVE | grep Disk | awk '{print $5}'`
CYLINDERS=`echo $SIZE/255/63/512 | bc`

sfdisk -D -H 255 -S 63 -C $CYLINDERS $DRIVE << EOF
,9,0x0C,*
,114,,,
EOF
  • 每個柱面的大小爲255*63*512=8,225,280 Bytes
  • sfdisk的-D參數指定與DOS兼容,並自動在每一個分區前預留空間,以存放MBR(Master Boot Record);
  • 第一行分區描述,9,0x0C,*, 自動分配起始柱面,數量爲9,分區ID爲0x0C(表示FAT32分區),< bootable >爲*, 表示可啓動分區。
  • 第二行分區描述,114,,,, 一樣自動分配起柱面,數量爲114,其它爲默認。

現象

執行時,輸出的信息以下:it

Device Boot Start     End   #cyls    #blocks   Id  System
/dev/sdb1   *      0+      8       9-     72261    c  W95 FAT32 (LBA)
/dev/sdb2          9     122     114     915705   83  Linux
/dev/sdb3          0       -       0          0    0  Empty
/dev/sdb4          0       -       0          0    0  Empty

在安裝Linux的機器上運行,製做出來的卡沒有任何問題;但在虛擬機上的Linux系統(同一版本)上使用,製做出來的SD卡的啓動分區不能被設備識別。io

因爲設備須要讀取MBR引導啓動,因此極可能是MBR的數據有問題。table

觀察到上面分區表的Start(起始柱面)爲0+,本人懷疑指定了-D參數自動預留給MBR的空間分配有問題,嘗試將起始柱面改成1後,就能夠正常從SD卡啓動:ast

sfdisk -D -H 255 -S 63 -C $CYLINDERS $DRIVE << EOF
1,9,0x0C,*
,114,,,
EOF

PS: fdisk提示第一個分區的起始柱面值範圍也是從1開始的!

結論

最終本人也沒有深究爲何在虛擬機上會致使這樣的問題。獲得的經驗是,使用sfdisk時,最好指定第一個分區的起始柱面爲1或以上,以免不一樣平臺下的行爲不一致。

相關文章
相關標籤/搜索