您好,  [请登录] [QQ登录]  [支付宝登录[免费注册]

商品分类

分享到: 百度搜藏 搜狐微博 新浪微博 腾讯微博 QQ收藏 人人网 Facebook Twitter

嵌入式Linux的safe mode计划与实现

发布日期:2011-04-12

 如今的种种嵌入式产品已经丰富多彩,它们正变化着我们的生存方法。随着嵌入式产品成果的增长,怎样让用户对已购买的产品的升级能寂静地、顺利地完成,克制升级进程中出现的不测失电所引起的产品妨碍,如许的题目请求嵌入产品计划开辟者在计划时就将产品的 safe mode 寂静模式思量进去。这里我们将以一个嵌入式Linux 网络播放器为例,来阐明 safe mode 寂静模式的计划与实现。通过本文,我们可以相识到针对一个实际的嵌入式体系,计划中必要细致的技能要点和实现细节。

  为什么必要 safe mode(寂静模式)

  当用户购买一个产品后,在后续的办事中,大概还会产生一些用度,让产品开辟商增长本钱,如免费德律风咨询,产品的维修、寄送。以是说将产品的卖出并不料味着终极的赢利。如许的环境下,产品的计划就必要越发公道,越发优化,来餍足用户种种大概的需求。分外是在产生非常妨碍的时间,要是能引导客户自行完成诊断、修复,那么将大大低掉队续的办事本钱。正由于云云,产品妨碍时,就很必要safe mode寂静模式来资助用户完成规复的事变。

  从节省产品的本钱、产品所能提供的成果上来看,safe mode 是大有裨益的。

  大家所熟知的 windows 体系,也提供了 safe mode 寂静模式,它就可以资助用户办理体系不稳固,硬件辩论等诸多妨碍,让用户在本身可以操纵的本领范畴内先行对体系举行诊断与修复。在很大程度上, windows 的 safe mode 给用户与 Microsoft 都带来了很大的方便。

  嵌入式Linux产品与其他IT产品差别的地方,重要是利用flash来存贮运行时的体系。它没有大的内存,没有大的存储空间,但它却也是一个完备的体系。

  在通常环境下,嵌入式Linux产品的flash上的内容是不会被粉碎的,也即它们会有着较好的稳固性,不会由于用户的老例利用而导致flash上的 firmware被粉碎。但随着产品的更新升级,用户也必要在本身家中完成对已购买商品的更新换代。而用户大多属于非技能熟习者,在更新升级中就大概出现种种意想不到的环境。

  比如在用户做firmware升级更新时,平常不会出现题目的firmware大概在这个进程中,就面对着巨大的危害,极有大概致利用户的体系无法启动,不克不及正常事变。如许的环境是我们不肯意看到的,而实际中却的的确确大概会产生。

  思量如许一个场景:当用户对产品举行firmware升级时,要是在烧写flash的进程中,不测失电,那么用户手中的产品就将无法再次启动,由于 rootfs体系已经被粉碎了。用户所能做的,也只能将产品送回产商举行维修。如许来回的进程不但耗用度户的精力,同样也会增长产品开辟商的本钱。在产品升级换代很快确当前市场环境下,如许的环境大概会通常产生。

  怎样克制如许的环境的产生呢?要是我们可以提供一个机制,在举行升级前即往flash中写入一个标记,正常完成后,再写入另一个标记来表现整个进程的正常结束,不然的话,烧写时失电不会写入第二个标记,只有第一个标记,那么就以为产品妨碍,这个时间,进入另一个新的提示界面,让用户本身选择从 USB或FTP来重新升级firmware。如许的话,整个进程用户就完全可以在界面的友爱提示下本身完成,方便了用户与产品开辟商。

  体系架构

  本文以一个实际的产品为例,来阐明safe mode的计划。

  体系架构

体系架构

  本体系为一个嵌入式Linux网络播放器,重要的成果为播放家庭网络中的多媒体文件,在家庭客堂等环境中有着大量的应用,它可以给用户提供更方便快捷的媒体文件的播放方法,并能充分利用家庭音响体系的巨大成果,而非PC环境下有限的外部配置,大大改进了媒体文件的播放体验。

  本体系的架构如下图:

本体系的架构

  产品所利用的flash总大小为16M。

  体系包括三大部分,即Bootloader,config, kernel + rootfs:

体系包括三大部分,即bootloader,config, kernel + rootfs

  别的,/dev/mtdblock/0,在体系中映射整个flash block,即整个16M空间。

  体系启动时,bootloader将kernel和根文件映象从flash上读取到RAM空间中,为内核设置启动参数,调用内核,进入application,举行媒体文件的播放。

  这个通常意义上的嵌入式Linux体系,它是不带safe mode寂静模式的。

  如许的体系,在做体系更新升级时,重要是对kernel+rootfs部分举行升级,以此来增长体系的成果。

  升级时,application重要是操纵/dev/mtdblock/3配置文件:

  第一步:下载新的firmware到ramfs中,也即ram disk中,比如/tmp目次下,采取的更新方法可以是USB或FTP;

  第二步:read /tmp/firmware文件,并write到配置文件/dev/mtdblock/3上,即对已有的firmware举行了更新。

  在升级的进程中,我们会提供友爱的界面给用户,来提示下载进度与烧写flash的进度,让用户可以看到正在产生的状态。

  末了烧写完成后,重新启动体系,即可进入到新的firmware中。

  在通常的更新中,用户的产品配置config一样平常不去修改,保持用户已经做的配置选项,不克不及粉碎。Config内容映射为/dev/mtdblock/2配置文件。

  从USB/FTP 上更新时,所利用的firmware文件必要是一个越发完备的image文件,可以包括bootloader, default config, kernel+rootfs,并让application可以做到视image中的标记来决定是否必要更新bootloader、config等内容,如许会越发机动。

  在更新firmware时,要是失电,那么kernel + rootfs部分将会出现不完备的环境,也便是说只写入了部分内容,而中途停止了,如许的话,一个不完备的体系将无法正常事变。在如许的环境下就必要safe mode寂静模式了。

  safe mode架构计划

  Safe mode的计划中,对原来的体系增长了两个部分的内容:

  kernel + rootfs,即大略的UI界面与成果;

  magic number,即烧写flash的标记。

safe mode架构计划

  safe mode实际上也是一个kernel + rootfs部分,只是它所具有的成果只包括一些大略的界面,重要是提供网络设置,从USB/FTP下载firmware,完成对flash的烧写。

  为了区分,这里,将主成果部分的kernel + rootfs称为master。

  我们将safe mode存放在master的后部,预留的flash大小为4M。

  Magic number只占用一个字节的大小,是在这4M的末了的部分的一个字节,也即原始体系的15872K的末了一个字节位置处。

  在开始烧写flash前,将magic number设置为0x55,表现烧写的开始。烧写正常结束后,将magic number设置为0xAA,表现烧写正常结束。

  要是新产品中具备了safe mode模式,那么在以后再次更新升级时,开始烧写flash时,magic number的位置将会有0x55标记,要是烧写中途失电,在重新启动后,将由Bootloader来查抄magic number的值,要是内容为0x55,那么bootloader将从safemode部分读出kernel和根文件映象,再为内核设置启动参数,调用内核,进入safe mode application。

  要是bootloader读到magic number为0xAA,那么阐明master firmware是正常的,就将直接进入master。

  以是涉及到safe mode的地方也包括了对bootloader的修改,必要在体系上电阶段也查抄safe mode的magic number,这个进程是必不可少的,只有在启动阶段就查抄magic number,才华跳过破坏的master体系,进入寂静模式,到达规复体系的目标。

  safe mode架构实现

  在safe mode的实现中,必要保持原有master部分的稳固,以是对master体系的building system不做大的窜改,也便是保持safe mode的building system与master的building system共存。原则上来说,要克制对master体系带来大的辩论。

  Master building system重要涉及到的编译进程为:

  make

  make rootfs

  这个时间将得到master.bin

  safe mode building system和其雷同,只是make rootfs部分有所区分:

  make

  make smrootfs

  这个时间将得到safemode.bin

  末了再将master与safe

  mode部分做一个归并,得到一个整的rootfs

  make dualrootfs

  make dist

  make

  dualrootfs将调用一个外部的步伐make_dual.c,所做的事变是要得到一个15872K的rootfs。这个rootfs包括的内容为master.bin + safemode.bin。

 本体系中一样平常master.bin的大小约为10000K,再加上safemode.bin的4M,总大小并未到达15872K,那么中间多出的部分,我们必要将其补0添补好。必要补充的0的大小约为15872-4*1024-10000=1776K

本体系中一样平常master

  make_dual.c便是完成上面的归并,补0的事变。它read master.bin,write rootfs,然后write 1776K个零到rootfs中,接下来read safemode.bin,再连续write 到rootfs中。

  如许就得到了完备的、带master与safe mode的rootfs。

  safe mode实现中遇到的题目及其办理

  体积限定:

  在safe mode的开辟中,起首遇到的一个题目便是怎样从已有的体系中简化出一个safe mode的application环境。

  对master原有体系的裁剪来得到safe mode,将会比较容易,要是重新另写一套,将会耗费较大精力,稳固性也无法得到确实的保障,以是终极采取的是精简master的体系来得到safe mode的大框架。

  在实现safe mode时,要做的事变的原则是做到safe mode的rootfs只管即便小,低于4M,并且保持与master外围特性的同等,如许可以克制重复开辟,同期间码的共用可以淘汰维护的不便,进步整个体系的机动度、稳固度。

  就一个能运行的嵌入体系来说,最根本的内容应该包括Linux kernel,busybox东西包、图形驱动等内容。

  在本体系中,为了支持FTP下载,必要有network的支持,也即必要包括wired/wireless的支持。

  为了支持USB下载方法,就必要USB monitor办理进程的支持,这个重要是保持了与master体系的同等,而没有别的去写一个别积更小的USB办理模块。

  wireless模块:

  原来在计划时,可以思量不参加wireless的支持,但为了越发方便用户,保持用户的利用风俗,我们还是参加了对wireless的支持,如许也保持了与master体系的同等,但支持的价格是,safe mode的体积增大了约莫250K。

  在wireless module中,做了一个优化,master体系中wireless module在insmod时,是利用的rootfs中的/lib/module/wireless/XXX.o,这些未压缩的.o文件在rootfs体系中将占用较大空间,如许一来,映射的safe mode的内容将会高出4M的大小。为了办理这个题目,我们将这些wireless module压缩成wireless.tar.gz文件,安排到safemode.bin中,在Linux启动时,在/etc/rc脚本中将 wireless.tar.gz解压缩到ramfs中即/tmp/lib/module/wireless下,然后再从这里insmod安置 wireless模块。如许所做的高兴,wireless module从原来的790K,缩减到了250K,而成果保持了同等。

  字体:

  master 体系的字体利用的是freetype2,字体文件arialbd.ttf约莫为280K,这也将占用大量的空间。由于safe mode在表现界面方面没有过高的请求,能让用户看到根本的图形界面就已经到达目标了,以是在safe mode中必要将freetype去失。但由于master模式与safe mode都利用雷同的图形引擎,如许就导致了,要是在safe mode中去失freetype,那么就必要再次重新build底子的图形库,如许在master与safe mode的单独编译进程中就必要重复去make clean这些库。这会给每次的编译带来很大的不便,每次make clean等操纵会占用大量的时间,耗时耗力。

  基于这个思量,我们决定master与safe mode在编译进程中都利用雷同的图形库,即都编译天生freetype库。但在运行时,safe mode不去利用freetype。也便是说,freetype库会被编译进来,但字体文件不必要加到safe mode中,如许做的价格便是编译出来的safe mode的application比完全无freetype库的环境要大100K左右,但却保持了与master雷同的库布局,而freetype字体就不再必要了,也就节省出了约莫280K的空间。

  终极优化的结果,safe mode的4M,包括Linux kernel, buzybox, safe mode application等压缩后的大小:

  优化结果 

优化结果

  后续版本的兼容:

  在safe mode的计划中,对后续多个版本升级的支持也是一个必要细致思量的地方。由于后续版本会存在很多的不确定性,要是发出的版本不克不及很好地兼容后续版本,那么将会给产品带来巨大的危害。

  后续版本的大概环境,重要分两种:布局分区变革不大,布局分区变革巨大。

  对后续版本中变革不大的环境,也即雷同master + safe mode的环境,当再次更新时,只必要操纵/dev/mtdblock/3映射master,/dev/mtdblock/4映射safe mode,即可。

  但要是后续版本变革非常大,那么就必要分外细致了。

  可以思量如许一个环境:要是后续的版本,需求产生了大的变革,比如必要将原来master地点的分区再分成多个分区:

  后续版本需求变革

后续版本需求变革

  那么从老版本升级到新版本时,这些分区的内容怎样包管烧写后能正常事变呢?

  办理的步伐便是在老版本中,将后续的rootfs部分作为一个团体来操纵,也便是说烧写时,是将master + part1 + part2+ safe mode作为一个团体来对待。在老版本看来,新版本中的这15872K的内容,不管它此中有多少个差别的分区,还是master + safe mode。在烧写时,还是按/dev/mtdblock/3映射master,/dev/mtdblock/4映射safe mode的方法来烧写,完成将15872K的内容完备烧写进flash即可。

  为了做到这一点,在烧写中,我们将全部的15872K的内容分成两段,第一段为15872-4*1024=11776K,必要将其write到/dev/mtdblock/3中,第二段为4M,必要将其write到/dev/mtdblock/4中。如许全部的15872K的内容就完备地烧写完,而再次启动后的kernel会辨别出 master + part1 + part2 + safe mode,它们的总大小依然保持15872K稳固。这整个进程中,都不消去分析新版本中到底包括哪些内容,哪些分区,只要包管是将15872K的内容全部完备地烧写进去就可以了。

  团体rootfs的计划头脑在这里帮了一个大忙,简化了升级更新时所必要思量的巨大度,使计划变得越发机动与易于维护。

  如许才新颁布的firmware里,要是分为多个分区,那么就包管再次升级时,将15872K的内容分成多段,写到雷同/dev/mtdblock/3、4、5、6如许的配置文件里就可以了,只要包管这些地区是连续的、并且烧写的内容是全部的那15872K内容即可。

  Magic number:

  值得细致的是,随着差别的版本的变革,magic number的位置还是应该保持在15872K的末了一个字节的位置。但这就出现一个题目,在差别的版本中,这个magic number的位置会是在差别的partition的末了一个字节。比如某个版本大概是在/dev/mtdblock/4的末了,但再后续的版本它会变成了/dev/mtdblock/7的最背面,如许就会存在很大的不确定性。以是在一个各个版本中,写magic number标记位时,必要一个同一的要领来做到这件事。最容易想到的步伐固然便是magic number这个位置相对肇始位置0是稳固的。而前面提到过的/dev/mtdblock/0就恰好是代表了可以操纵的整个flash分区。

  有了/dev/mtdblock/0,如许我们就可以open 它,seek到magic number的位置,然后write下0x55或0xAA,如许就保持了写magic number的代码的同等性,不必要根据差别的分区,多次修改操纵magic number的有关函数。

  Booloader:

  Bootloader的修改,也涉及到对magic number的读取,它的读取就相对大略一些,直接利用magic number在RAM中映射的绝对地点即可。

  Bootloader查抄完magic number后,必要将相对地点为0xBC0000的safe mode的kernel + rootfs读入到RAM,然后设置启动参数,调用内核,进入safe mode提示界面。

  Linux kernel:

  与老的、不带safe mode的image相比,新的image里的Linux kernel从总体的角度来说,并没有大的变革。在新做的master与safe mode的image中,它们各自必要包括一个Linux kernel,这两个kernel唯一的差别便是启动时所必要的rootfs在RAM中的映射位置差别。它们都有着雷同的partition分区设置,编译选项等。

  Safe mode必须包括本身的Linux kernel,由于它是运行在master破坏的环境下,master kernel已经不克不及启动了。

  总结

  上面的内容是在实际开辟中对safe mode的计划与实现的一个形貌。从这个形貌中,可以看到safe mode在嵌入式Linux产品扮演着紧张的角色,对它的计划涉及到很多方面,要思量体系的尺寸,与现有buidling环境的的兼容性,对后续版本的升级的兼容性等诸多方面。

  从某种意义上来说,safe mode的计划干系到产品的成败,一个好的safe mode的计划将会给产品带来巨大的机动性与可扩展性,大大地方便了客户与产品开辟商。