因爲工做上須要常常要爲嵌入式設備製做啓動SD卡,所以本人使用sfdisk編寫了自動分區、格式化和安裝文件的腳本。(不選擇fdisk是由於它是爲用戶交互設計的,在腳本上使用不夠方便)spa
實際使用過程當中,有同事反饋在有些機器的虛擬機上使用,製做出來的卡不能啓動。通過一番排查,終於搞清楚問題所在。設計
先從結論來講,使用sfdisk時,最好指定第一個分區的起始柱面(cylinder)爲1或以上!code
截選自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
,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或以上,以免不一樣平臺下的行爲不一致。