减少车载电脑应用系统的操作系统启动时间,第三部分

作者:Damien Stolarz

这是关于减少车载电脑启动时间的三部分系列文章(参见“资源”部分)的最后一篇。该项目的动力来自我的公司 CarBot,我们致力于使车载电脑硬件表现得像它在汽车中应有的样子。在前两篇文章中,我讨论了一系列解决启动缓慢问题的方法。自从那些文章撰写以来,我们彻底探索了在 VIA Epia-M 主板上使用 BIOS 替代方案的可能性,以尝试将启动时间缩短到理论上的最小值。在此期间,我们还发现了一些可以用来最大限度地减少启动时间对用户体验的影响的技巧。

在之前的文章中,我们将不必要的缓慢启动过程比作汽车收音机。汽车收音机的启动时间从 1980 年代的几乎即时启动已经攀升到今天的几秒钟,但它们仍然足够快,几乎不引人注意。如果您在启动引擎后立即观看现代收音机,您可能会看到它进行一个小的开机自检,闪烁设备上的所有指示灯——就像许多汽车的仪表板一样——然后打开放大器,在一两秒钟内发出声音。

我们决定使用收音机作为快速可用性和类似家电行为的基准。我们试图最大限度地减少以下两个变量:从电脑开机到视频显示的时间以及从电脑开机到音频输出的时间。

我们的测试理由是,如果我们能够最大限度地缩短启动过程中音频和视频到达的时间,我们稍后就可以优化我们的软件,以便恢复用户上次看到和听到的任何内容。这就是收音机所做的,这就是电视所做的,这就是电脑应该做的。

用户需要几秒钟的时间来适应手头的任务,例如配置车载电脑。如果屏幕看起来像上次关机时的样子,它至少会给人一种开机的错觉,并且会稍微减少一些烦恼。《人性化界面》一书中,Macintosh 电脑之父杰夫·拉斯金断言,计算机根本没有技术理由需要任何启动时间。

减少启动时间可以通过蛮力或技巧来完成。我们已经发现或被告知的解决方案可以分为三个基本类别

  1. 将启动时间减少到理论上的最小值。

  2. 在电脑启动时分散用户的注意力。

  3. 预测用户,并在用户有机会等待之前启动。

最小化启动时间

很久以前,我在 Linux BIOS 页面上看到一条评论,说 EPIA-M 支持存在,但不稳定。自 2003 年 7 月以来,这一事实没有改变。我给该分支的维护者发了电子邮件,他说:“我最快的时间是 5 秒,并对 [init] 脚本进行了一些优化。”

哇,五秒钟。我们想要达到这个目标。

最初,我试图找到一家商业供应商来替换 BIOS。General Software 非常友好地寄给了我一份用于 EPIA-M 的 BIOS 替代方案样品,但该公司尚未为 EPIA M2(我们在产品中使用的另一种主板)提供类似版本。此外,我询问的几家供应商的入门价格出奇地一致——大约 10,000 美元。我想,收回定制 BIOS 的努力需要这种定价。部分问题是这些 BIOS 实现做了各种很棒的事情,而我们正在寻找的是一个几乎什么都不做的 BIOS。

因此,我们开始研究通过抛弃 BIOS 并自行启动 Linux 可以挽回多少时间。我们的想法是抛弃所有无用的 BIOS 功能,在引导加载程序(即 GRUB 启动画面)中显示视频,并在启动序列中尽早开始播放音频。

替换 BIOS

我们的 Linux 工程师 James 被派去使用两块 Epia-M 主板、一个可启动的 256MB 闪存驱动器、前两篇启动文章和一个指向 LinuxBIOS 站点的指针。我最初认为我们可以将足够的 Linux 放入 BIOS 芯片本身以做一些有用的事情,例如发出声音和闪烁显示器。这将满足我们的光和声音目标,但 James 发现,如果不使用闪存驱动器,我们没有足够的空间。因此,新的目标是尽可能减少 BIOS 启动时间,然后在紧凑型闪存 IDE 驱动器上启动精简的 ZipSlack 发行版

LinuxBIOS 对于我们应用的主要好处也是主要的缺点。主要开发重点是制造需要能够快速重启的超级计算机集群。然而,这些集群是为网络启动而设计的;我们想从磁盘或闪存设备启动。

EPIA-M 主板虽然在 硬件破解领域 非常流行,但在集群超级计算节点中并不流行。EPIA 不是最快的主板,运行频率在 600MHz 到 1GHz 之间,CPU 相对较弱。

随着 LinuxBIOS 项目的进展,一些用于执行超级计算机节点引导以外操作的代码已经与文档不同步。下载并阅读大部分 LinuxBIOS 邮件列表存档 有助于调和这些差异。例如,有一段时间,Etherboot 模块似乎可以适应从其他设备(例如我们使用的紧凑型闪存/IDE 适配器组合)启动。最终,James 切换到使用 FILO 引导加载程序。

刷新 BIOS 的硬件方面是最冒险的。新 BIOS 映像的最初几次编译自然会产生无法启动的机器。BIOS 编程工作的基本工具是两块相同的主板和 正确的芯片镊子

修复烧坏的 BIOS 似乎是错误的,当您正在这样做时。当您在计算机 A 中烧坏 BIOS 时,您启动计算机 B 并使用修复的 BIOS,然后在计算机仍在运行时小心地取出其芯片。然后,您将另一个 BIOS 芯片放入其位置,并使用原始 BIOS 的备份来烧录它。然后,您可以将芯片放回另一台计算机并继续您的工作。

获得可用的 BIOS 并非易事。Etherboot 会因各种迷人的原因而失败,例如找不到以太网卡,找不到磁盘上的内核等等。在十几次失败的尝试之后,最终刷新了一个可启动的 BIOS,并且 ZipSlack 从 CF 卡成功启动。

以下几个部分由 James 编写,详细介绍了在此过程中发现的内容。

如何安装实验性 BIOS
  1. 关闭电源。用记号笔在您的良好 BIOS 上标记 G,在实验性 BIOS 芯片 上标记 X,以便您可以区分它们。拿起芯片镊子工具。如果间隙足够大,将钩子穿过插槽角落提供的插槽,将工具压在插槽上并挤压。如果间隙不足以容纳两个钩子,请展开工具,将一个钩子放在一个角下,将工具压在插槽上并轻轻挤压,直到芯片开始升起。然后,移动到另一个角,然后再回到第一个角,依此类推。您希望芯片笔直地出来,否则会弯曲触点。

  2. 按下好的 BIOS——确保方向正确。有可能倒着插进去,这会烧坏芯片。您不必将芯片一直推入插槽底部。

  3. 启动。您需要确保您的发行版或闪存或其他东西在您刷新 BIOS 之前启动。

  4. 一旦它开始启动,您就可以拔出好的 BIOS,因为它已被复制到影子 RAM 中。如上所述将其拔出,注意不要使主板短路或损坏任何东西。

  5. 推入实验性 BIOS。

  6. 获取您的固定 BIOS,无论您选择如何操作,并使用 FreeBIOS flash_and_burn 目录中的 flash_rom 烧录它。我发现我经常需要烧录两次,或者至少必须通过运行不带参数的 flash_rom 来唤醒芯片以使其执行芯片 ID 操作;我不知道为什么。

  7. 重启并查看它是否工作。

创建更快的启动映像

步骤顺序如下:开机加载 FreeBIOS,FreeBIOS 加载引导加载程序 (FILO),引导加载程序加载内核等等。首先,您必须构建引导加载程序。FreeBIOS 人员喜欢使用 Etherboot,但 Etherboot 目前在从磁盘启动方面已损坏。因此,FILO 是要使用的东西。FILO 就像 GRUB,但它不需要 BIOS。

解压缩 FILO,切换到 FILO 目录并运行make。这将创建一个默认配置文件。编辑 config,然后再次运行make再次运行以创建 filo.elf,这是我们用于 LinuxBIOS 负载的内容。这是我的 FILO 配置

接下来,我们需要添加一个视频 BIOS。实际上,Epia-M 上的视频 BIOS 非常无用(稍后会详细介绍),但它可以让 X 知道我们有内置视频,所以它进去了。

由于视频 BIOS 受 VIA 版权保护,不能独立分发,因此您必须从原始 BIOS 中获取它。通过两种方式之一执行此操作。要么启动 Linux 并输入

dd if=/dev/mem of=vgabios.bin skip=1536 count=128

要么从 BIOS 发行映像中提取它,如果您可以找到偏移量。将两者连接在一起,如下所示

cat vgabios.bin filo.elf > vfilo.elf

因此,vfilo.elf 是我们的负载——引导加载程序加上视频 BIOS。

传统的 LinuxBIOS 现在被称为 FreeBIOS,因为它可以加载 Linux 以外的东西。一个新的重写版本,称为 FreeBIOS2,似乎尚未准备就绪。因此,我使用了 FreeBIOS,它仅可从 CVS 获得。要获取它,请键入

cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/freebios login
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/freebios co freebios

FreeBIOS 在一个单独的目录中构建和配置,因此执行 CVS 更新不会破坏您现有的配置文件。因此,在与 /linuxbios 相同的目录中,通过发出以下命令创建 build 目录mkdir build。然后,创建一个 epia-config 文件;这是我们的 epia-config 文件

注意该文件中的所有完整路径?LinuxBIOS 喜欢完整路径。要构建 BIOS,请执行以下操作

python /home/jamesh/linuxbios/freebios/util/config/NLBConfig.py
epia-config/home/jamesh/linuxbios/freebios/

其中/home/jamesh/linuxbios/freebios是我放置 FreeBIOS 的位置。然后运行make,它应该生成一个名为 romimage 的文件。这就是您烧录到 BIOS 芯片的内容。

您还需要来自 FreeBIOS 人员的一些实用程序。cd进入 freebios/util/mkelfImage 并发出

./configure && make && make install

以获取 mkelfImage,它应该最终出现在 /usr/local/sbin 中。然后,cd进入 ../flash_and_burn 并执行make以获取 flash_rom。这就是您将用来刷新 ROM 的程序。

顺便说一句,还有一些其他工具可以生成 ELF 内核——不要使用它们。它们中的大多数都已损坏,包括 HOWTO 中提到的 Etherboot 项目中的工具。

下一步——构建内核

Epia 补丁包括一个名为 epia-fbdev 的补丁,这导致 LinuxBIOS 邮件列表中的以下鼓励

El Jueves, 13 de Mayo de 2004 18:46, John Laur escribi?:
> If you have VGA correctly working with LinuxBIOS (Ie you see the
> linuxbios logo on startup), then you have VGA working as best it does
> with LinuxBIOS.
>
> Then you can worry about the kernel. VESA Framebuffer does not work with
> EPIA-M as the VGA bios doesn't initialize the video card up to where
> vesafb can take over. You have to use viafb (part of the -epia patchset)
> to get video on the console. Make sure you have it compiled into the
> kernel and not as a module. Make sure vesafb is NOT compiled in either,
> otherwise you'll need some commandline trickery to make it work. Also,
> viafb doesn't work with bootsplash in silent mode on kernel 2.4 if you
> are using that. I have not tested with kernel 2.6.
>
> John

但是,我尝试过的所有 epia-fbdev 版本都使机器挂起或产生乱码文本。

无论如何,应该以正常方式构建内核。我解压缩了内核,配置了它并发出

make dep && make bzImage
&& make modules

然后,为了将模块安装到某个地方以便我可以将它们复制到闪存,我输入了

INSTALL_MOD_PATH=/home2/jamesh/linux-fast/ make modules_install

该命令创建了 /home2/jamesh/linux-fast/lib/modules/2.4.26-fast/。接下来,从内核中创建一个 elf 映像。这使您可以将命令行参数放在内核文件中,并允许引导加载程序确定内核的大小

/usr/local/sbin/mkelfImage --kernel=linux-2.4.26-fast/arch/i386/boot/bzImage 
    --output=bzImage-2.4.26-fast.elf --command-line="root=/dev/hda4 console=tty0 console=ttyS0,115200n8 rw"

请注意,我设置了 root=/dev/hda4。我还像这样设置了 FILO

AUTOBOOT_FILE = "hda4:/bzImage"

现在,我只需要将内核放在 /dev/hda4 的根目录中——很简单。接下来,将 romimage 和 flash_and_burn 文件复制到您的 Epia 盒子上并运行flash_and_burn本身,看看它是否识别您的闪存芯片。输入flash_and_burn romimage烧录它。

现在,将终端连接到串口,设置为 115200-n-8-1,然后启动。在 20 秒内,您应该听到 Dexter 的声音,假设您正在使用 我的 ZipSlack 映像。如您所见,X 工作正常,但鼠标不起作用——我不知道为什么。输入startx启动 X。

我创建了两个磁盘映像。一个是 UMSDOS,我将其解压缩到磁盘分区 4 上的 MS-DOS 文件系统中。另一个是 tar 文件,应该可以在 ext2 或 ext3 文件系统上工作。

启动时间结果

我们成功启动的完整日志以及细粒度计时 在此处,以下引导式浏览将带您了解重点。

我编写了一个程序来转储来自串口的控制台输出,并带有时间戳。以下是一些需要注意的有趣的事情

  • 从开机到 BIOS 需要 0.334 秒。

    > 3.492 Copying LinuxBIOS to ram.
    
    
  • 三分半钟,现在它正在将 BIOS 复制到影子中。我假设时间花在了寻找影子本身上。

    > 6.292 Jumping to LinuxBIOS.
    
    
  • 这是一个主要的浪费时间的地方:从闪存 BIOS 芯片读取速度很慢。

    > 6.616 POST: 0x75
    > ...
    > 7.076 POST: 0x95
    
    
  • 我不知道这到底意味着什么。

    > 7.153 found VGA: vid=1106, did=3122
    > ...
    > 9.533 biosint: Unsupport int #0xcd
    
    
  • 这尝试运行我安装的视频 BIOS。可以通过删除 FreeBIOS 构建目录中 epia-config 中的dir src/bioscall行来节省 2.38 秒。我目前拥有的唯一跳过此步骤的版本也没有向串口发送任何内容,因此我没有它的日志。

    > 9.574 Welcome to elfboot, the open sourced starter.
    
    
  • 我们还没有脱离 LinuxBIOS。

    > 9.722 FILO version 0.4.2 
    
    
  • 我们终于脱离了 LinuxBIOS 并进入了 FILO 引导加载程序。

    > 9.792 No sound device found
    
    
  • 是的,该消息在 FILO 中。如果您有 FILO 识别的声音设备,它会在此时播放声音。但是,我无法让它找到 VIA 声卡,当然我也没有非常努力地尝试。但是,如果您使用的是带有独立显卡和 SB 兼容声卡的主板,我们将在不到十秒的时间内获得图像和声音。

    > 10.013 Loading Linux version ...
    > 12.242 Jumping to entry point...
    
    
  • 嗯,将内核从闪存中取出并放入 RAM 中需要两秒多。

    > 13.252 Linux version 2.4.26-fast
    
    
  • 这是 Linux 启动的实际开始。

    > 19.811 Playing Sound
    
    

此时声音正在声卡中播放——19.811 秒,或者如果跳过视频 BIOS 调用,则为 17.431 秒。其中,只有 6.559 秒实际上是在启动 Linux。

结论

我们没有获得我们希望的五秒启动时间。其中几个原因特定于我们使用的 EPIA 主板。板载 EPIA 视频也带来了问题,因为其自身的视频 BIOS 是计算机 BIOS 的一部分。如果它是一个单独的显卡,则可以完全跳过其初始化,留给 X 在启动时执行。同样,如果我们使用更传统的声卡,例如旧的 SoundBlaster,我们可以在启动过程中更早地获得声音,大约在十秒左右。

然而,该练习确实说明了许多有用的东西。它使我们能够精确地分解时间损失在哪里,并且它确实给了我们一个较低的阈值——大约十秒——我们知道在给定的主板和硬件条件下,我们可以向用户输出声音和视频。而这还是从冷启动开始,按下电源开关。

尽管我们从未让视频显示出来,即使在 X 启动后,这方面的好消息 是在本文完成时传来的。Nick Barker 已经完成了 EPIA-M2 主板的 FreeBIOS 实现,它似乎不仅解决了视频问题,还解决了这些主板上直接从 CF 插槽启动的长期难题。通过进一步的工作,我们可以将我们的应用程序缩减到这个新的理论上的十秒最小值。

但是,还有其他方法可以减少车载电脑的启动时间。最后,我将列出一些我们尚未涵盖的选项。

  • 显而易见的方法包括蛮力——使用更快的处理器和硬件。

  • 从固态串行 ATA 硬盘驱动器启动,例如 M-Systems 的 Fast Flash Disk (FFD) 2.5 英寸 Ultra ATA 或 BitMicro 的 E-Disk

  • 休眠,将内存状态保存到硬盘并在启动时恢复它,是一个很好的工具。但是随着内存大小的增长,此解决方案的速度会降低。

  • 模拟 PalmPilot:在汽车中安装第二块电池,使用电压隔离器,并使计算机始终运行。它将在您唤醒它时在几秒钟内休眠和启动。

  • 安排您的计算机。使用某些计算机中的 BIOS 唤醒功能,将其设置为在您通常早上上班前几分钟唤醒。通过这样做,它将在您到达汽车之前完全启动。

  • 上一篇文章的一位读者建议使计算机在您打开车门时而不是在您转动钥匙时开始启动。对该技术的改进是在用户使用遥控无钥匙进入系统解锁车门后立即启动。

随着通用计算机越来越多地进入汽车,人们将不断努力解决启动时间问题。

Damien Stolarz 是一位发明家、作家和工程师,在使不同类型的计算机相互通信方面拥有多年的经验。他是车载电脑公司 CarBot, Inc. 和硬件及软件开发公司 Robotarmy Corp. 的首席执行官。

加载 Disqus 评论