前言

由于工作上需要经常要为嵌入式设备制作启动SD卡,因此本人使用sfdisk编写了自动分区、格式化和安装文件的脚本。(不选择fdisk是因为它是为用户交互设计的,在脚本上使用不够方便)

实际使用过程中,有同事反馈在有些机器的虚拟机上使用,制作出来的卡不能启动。经过一番排查,终于搞清楚问题所在。

先从结论来说,使用sfdisk时, 最好指定第一个分区的起始柱面(cylinder)为1或以上 !

基础知识 - sfdisk使用

截选自 man sfidsk :

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 >。如果参数没有指定,则使用默认值;而<起始柱面>的默认值为当前最小可用的柱面编号。

因此最初编写出来的脚本类似这样:

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,其它为默认。

现象

执行时,输出的信息如下:

   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卡的启动分区不能被设备识别。

由于设备需要读取MBR引导启动,所以很可能是MBR的数据有问题。

观察到上面分区表的Start(起始柱面)为 0+ ,本人怀疑指定了-D参数自动预留给MBR的空间分配有问题,尝试将起始柱面改为1后,就可以正常从SD卡启动:

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

PS: fdisk提示第一个分区的起始柱面值范围也是从1开始的!

结论

最终本人也没有深究为什么在虚拟机上会导致这样的问题。得到的经验是,使用sfdisk时,最好指定第一个分区的起始柱面为1或以上,以避免不同平台下的行为不一致。

sfidsk创建可启动分区问题的更多相关文章

  1. 【转】使用命令行方式创建和启动android模拟器

    原文网址:http://blog.csdn.net/tiandinilv/article/details/8953001 1.Android模拟器介绍 Android中提供了一个模拟器来模拟ARM核的 ...

  2. EFI/GPT探索(为何win7分区时创建100M隐藏分区)

    EFI/GPT探索(为何win7分区时创建100M隐藏分区) 转自 http://blog.tomatoit.net/article.asp?id=348 EFI/GPT是新一代的固件/启动管理技术, ...

  3. Win7/Win8安装"我们无法创建新的分区,也找不到现有的分区"的解决方法

    如果你用pe启动光盘和pe启动盘.加载iso安装时遇到"我们无法创建新的分区,也找不到现有的分区"的情况.. 把iso里的boot和bootgmr以及sources复制到c盘,pe ...

  4. Java并发1——线程创建、启动、生命周期与线程控制

    内容提要: 线程与进程 为什么要使用多线程/进程?线程与进程的区别?线程对比进程的优势?Java中有多进程吗? 线程的创建与启动 线程的创建有哪几种方式?它们之间有什么区别? 线程的生命周期与线程控制 ...

  5. Java线程:创建与启动

    Java线程:创建与启动 一.定义线程   1.扩展java.lang.Thread类.   此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 R ...

  6. 04_线程的创建和启动_使用Callable和Future的方式

    [简述] 从java5开始,java提供了Callable接口,这个接口可以是Runnable接口的增强版, Callable接口提供了一个call()方法作为线程执行体,call()方法比run() ...

  7. 03_线程的创建和启动_实现Runnable接口方式

    [线程的创建和启动的步骤(实现Runnable接口方式)] 1.定义Runnable接口的实现类,并重写其中的run方法.run()方法的方法体是线程执行体. class SonThread  imp ...

  8. 02_线程的创建和启动_继承Thread方式

    [简述] java使用Thread类代表线程,所有的线程都必须是Thread或者其子类的实例. 每个线程的任务就是完成一定的任务,实际上就是执行一段程序流. [创建并启动多线程的步骤(集成Thread ...

  9. java线程 — 创建和启动线程

    创建和启动线程,传统有两种方式: 方式1:继承Thread类: 方式2:实现Runnable接口: 线程类(java.lang.Thread):Thread类和Thread的子类才能称之为线程类.阅读 ...

随机推荐

  1. Fedora14使用yum安装mysql

    linux下使用yum安装mysql   1.安装 查看有没有安装过:           yum list installed mysql*           rpm -qa | grep mys ...

  2. 剑指Offer面试题:8.二进制中1的个数

    一 题目:二进制中1的个数 题目:请实现一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 二 可能引起死循环的解法 // 计算整数的二 ...

  3. 重温CLR(七 ) 属性和事件

    无参属性 许多类型都定义了能被获取或更高的状态信息.这种状态信息一般作为类型的字段成员实现.例如一下类型包含两个字段: public sealed class Employee{ public str ...

  4. 剑指offer-第五章优化时间和空间效率(两个链表的第一个公共节点)

    思路1:要求的是两个链表的第一个公共节点,首先想到的是用栈来存放两个链表,然后依次从栈中抛出,直到最后一个相同的节点为止.但是要用到两个栈,空间复杂度为O(n): 思路2:从头到尾分别遍历两个链表得到 ...

  5. 剑指Offer-第一章面试细节总结

    面试细节:行为面试(20%)+技术面试(70%)+应聘者提问(10%) * 行为面试:跳槽者(不要抱怨老板,不要抱怨同事,只为追寻自己的理想而站斗) * 技术面试:1.基础知识点(编程语言,数据结构( ...

  6. vue指令总结

    new  Vue({          el: "#box",            // element(元素) 当前作用域          data:{ msg:" ...

  7. 【精品分享一】JAVA 精品图书高清PDF下载

    更多图书尽在第一云教育book.1eduyun.com JAVA核心技术卷2:高级特征(原书第8版) JAVA软件开发从新手到高手(Java从入门到精通(第3版)+Java项目开发全程实录(第3版)) ...

  8. Servlet概念入门

    什么是Servlet Servlet 为创建基于 web 的应用程序提供了基于组件.独立于平台的方法,可以不受 CGI 程序的性能限制.Servlet 有权限访问所有的 Java API,包括访问企业 ...

  9. 关于Apache Phoenix和Cloudera结合

    1. 安装: phoenix的官网最新版4.13.2是有parcle版本的,并不需要从cloudera的labs(实验室)中下载.安装完成后,可以运行一下phoenix的shell来简单验证一下:/o ...

  10. ubutun

    地址:http://www.cnblogs.com/dutlei/archive/2012/11/20/2778327.html