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或以上,以免不一样平台下的行为不一致。

相关文章
相关标签/搜索