嵌入式系统中自写根文件分区的升级方案

145 views
Skip to first unread message

Wick

unread,
Mar 6, 2012, 6:37:30 AM3/6/12
to 讨论组SZLUG
Hi,guys:

我现在有个需求。在没有备份根文件分区的系统上升级根文件系统,如何保证这种升级的稳定性?

主要要求是:板子Flash很小(8M),没有备份分区;Memory也很小,不能使用ramdisk;当然不用考虑掉电保护;

有谁做过这事儿?有啥好方法?

杨城

unread,
Mar 6, 2012, 6:49:59 AM3/6/12
to sz...@googlegroups.com

因为提到RAM小,应该是联机升级了。8M
Flash比较小建议直接重新擦除、写入,写后再读取校验,不成功再次擦除、写入。同时系统可以运行Linux应该RAM不会太小,如果可以直接使用loader修改一下升级程序就行了。

杨城

Wick

unread,
Mar 6, 2012, 7:12:44 AM3/6/12
to sz...@googlegroups.com
2012/3/6 杨城 <gump...@gmail.com>:

这里比我多了一个校验过程。

目前根文件系统使用了 Squashfs,我在linux系统中覆盖后再重启,一定会报错

SQUASHFS error: unable to read data cache entry
SQUASHFS error: unable to read data page, block fb790, size 839f

我觉得这似乎和文件系统类型也有很大关系。

--

杨城

unread,
Mar 6, 2012, 7:16:39 AM3/6/12
to sz...@googlegroups.com

如果非要一个文件系统的话,选择yaffs吧。不过才8M,重新擦写没有几分钟吧。

杨城

Wick

unread,
Mar 6, 2012, 7:28:40 AM3/6/12
to sz...@googlegroups.com

yaffs2 似乎没有啥优势啊。

而且时间没有问题,只要能保证稳定性。自己写自己实在是个不靠谱的事情。目前测试
- squashfs 一定出错
- jffs2 OK

因为压缩比的需要,我首先考虑squashfs,试试加入验证步骤。

--
今天能做的事绝不拖到明天
自己能做的事绝不麻烦别人

杨城

unread,
Mar 6, 2012, 7:49:35 AM3/6/12
to sz...@googlegroups.com

你现在的RAM有多大?能用squashfs就支持解压了,应该不太小啊

杨城

Wick

unread,
Mar 6, 2012, 7:51:59 AM3/6/12
to sz...@googlegroups.com
2012/3/6 杨城 <gump...@gmail.com>:
> 在 2012年3月6日 下午8:28,Wick <izha...@gmail.com> 写道:
>> 2012/3/6 杨城 <gump...@gmail.com>:
>>> 在 2012年3月6日 下午8:12,Wick <izha...@gmail.com> 写道:
>>>> 2012/3/6 杨城 <gump...@gmail.com>:
>>>>> 在 2012年3月6日 下午7:37,Wick <izha...@gmail.com> 写道:
>>>>>> Hi,guys:
>>>>>>
>>>>>> 我现在有个需求。在没有备份根文件分区的系统上升级根文件系统,如何保证这种升级的稳定性?
>>>>>>
>>>>>> 主要要求是:板子Flash很小(8M),没有备份分区;Memory也很小,不能使用ramdisk;当然不用考虑掉电保护;
>>>>>>
>>>>>> 有谁做过这事儿?有啥好方法?
>>>>>
>>>>> 因为提到RAM小,应该是联机升级了。8M
>>>>> Flash比较小建议直接重新擦除、写入,写后再读取校验,不成功再次擦除、写入。同时系统可以运行Linux应该RAM不会太小,如果可以直接使用loader修改一下升级程序就行了。
>>>>
>>>> 这里比我多了一个校验过程。
>>>>
>>>> 目前根文件系统使用了 Squashfs,我在linux系统中覆盖后再重启,一定会报错
>>>>
>>>> SQUASHFS error: unable to read data cache entry
>>>> SQUASHFS error: unable to read data page, block fb790, size 839f
>>>>
>>>> 我觉得这似乎和文件系统类型也有很大关系。
>>>>
>>>> --
>>>
>>> 如果非要一个文件系统的话,选择yaffs吧。不过才8M,重新擦写没有几分钟吧。
>>
>> yaffs2 似乎没有啥优势啊。
>>
>> 而且时间没有问题,只要能保证稳定性。自己写自己实在是个不靠谱的事情。目前测试
>> - squashfs 一定出错
>> - jffs2 OK
>>
>> 因为压缩比的需要,我首先考虑squashfs,试试加入验证步骤。
>
> 你现在的RAM有多大?能用squashfs就支持解压了,应该不太小啊

32M 不算小。但装 ramdisk 肯定不足了。

杨城

unread,
Mar 6, 2012, 7:57:47 AM3/6/12
to sz...@googlegroups.com

32M那还费这劲,直接用loader把RAM和Flash驱动起来,RAM分出2个8M。只要不启动Linux,你有大把的RAM可以用。不要想ramdisk,只想一片片的内存,32M啊写8M还纠结。当年256KRAM上写Nand
32M数据,那还怎么活啊

杨城

Wick

unread,
Mar 6, 2012, 8:02:07 AM3/6/12
to sz...@googlegroups.com

你理解错了。我的目的就是要在 linux 系统下完成根文件系统升级的。
系统进程很多的,跑起来只有10M free mem。搞一个ramdisk很快就out of memory

我看看验证加入后的反馈消息吧。先谢了。

--
今天能做的事绝不拖到明天
自己能做的事绝不麻烦别人

杨城

unread,
Mar 6, 2012, 8:05:47 AM3/6/12
to sz...@googlegroups.com

哦,理解了,你是只更新Flash中的一部分,那是我理解错了,不好意思

杨城

杨城

unread,
Mar 6, 2012, 10:30:56 AM3/6/12
to sz...@googlegroups.com

张兄,回家路上想了一下,之前说的可能不正确。就我的知识层面而言
首先squashfs是一个压缩的只读系统,只读的意思就是不可写,这也比较好理解,因为squashfs压缩后的镜像,是一个数据包,使用系统硬写入会破坏压缩包。这也比较好解释为什么jffs2就是OK。
这里有一个需求我没有理解,为什么必须在Linux系统下完成根文件系统升级的。如果是squashfs要更新,是需要将整个包重新写一遍,必须要重启后才使用更新了的系统。所以好象与当前运行的Linux系统没有太必然的联系。
其次如果只是需要修改几个配置数据,是否可以将Flash分区来操作,系统区基本不变,只更新数据区,数据区就不使用squahfs了。
如果必须要更新系统,同时又必须要在Linux下。则不要单独写文件系统下的文件,而是将整个镜像重新写入。写入后如下位机无RAM进行校验,就将数据传回PC进行校验。
多说一句,因为Flash有复写次数限制。如果频繁需要重新写一些数据,最好是考虑加入EEPROM保存数据。

之前说的有点"显"的意思,请不要介意

杨城

X Xiao

unread,
Mar 6, 2012, 4:34:37 PM3/6/12
to sz...@googlegroups.com
跑很多进程的同时更新ROOTFS,而且是只读的SQUASHFS,有点悬。
我的做法是,设置个最简化的内核+INITRAMFS+网络,放到一个1.5MB的分区里,升级时用这个简化内核启动,然后再开始系统升级更新,再启动复原到正常状态,重启前可以传参数到bootloader来告诉重启是选择哪个内核(产品用内核,还是简化内核)。
我这里的产品,还要考虑如何升级这个简化内核,还要考虑万一掉电怎么办,万无一失的升级挺难的,现在是把简化内核放到SPI里面,产品跑SD卡,一旦SD出问题就靠SPI和里面的简化内核救命。

-xxiao

Wick

unread,
Mar 6, 2012, 8:02:47 PM3/6/12
to sz...@googlegroups.com
>> 哦,理解了,你是只更新Flash中的一部分,那是我理解错了,不好意思
>>
>> 杨城
>
> 张兄,回家路上想了一下,之前说的可能不正确。就我的知识层面而言
> 首先squashfs是一个压缩的只读系统,只读的意思就是不可写,这也比较好理解,因为squashfs压缩后的镜像,是一个数据包,使用系统硬写入会破坏压缩包。这也比较好解释为什么jffs2就是OK。

我以前真心觉得直接操作device node 跟文件系统无关的。

> 这里有一个需求我没有理解,为什么必须在Linux系统下完成根文件系统升级的。如果是squashfs要更新,是需要将整个包重新写一遍,必须要重启后才使用更新了的系统。所以好象与当前运行的Linux系统没有太必然的联系。

这个需求其实很简单:如果这个东西能确保稳定性,我希望他能够产品化,客户可以登陆盒子的web页面进行升级... 因此必须在linux里来做。

> 其次如果只是需要修改几个配置数据,是否可以将Flash分区来操作,系统区基本不变,只更新数据区,数据区就不使用squahfs了。
> 如果必须要更新系统,同时又必须要在Linux下。则不要单独写文件系统下的文件,而是将整个镜像重新写入。写入后如下位机无RAM进行校验,就将数据传回PC进行校验。
> 多说一句,因为Flash有复写次数限制。如果频繁需要重新写一些数据,最好是考虑加入EEPROM保存数据。
>
> 之前说的有点"显"的意思,请不要介意


客气了

Wick

unread,
Mar 6, 2012, 8:05:18 PM3/6/12
to sz...@googlegroups.com
2012/3/7 X Xiao <fos...@gmail.com>:

> 跑很多进程的同时更新ROOTFS,而且是只读的SQUASHFS,有点悬。
> 我的做法是,设置个最简化的内核+INITRAMFS+网络,放到一个1.5MB的分区里,升级时用这个简化内核启动,然后再开始系统升级更新,再启动复原到正常状态,重启前可以传参数到bootloader来告诉重启是选择哪个内核(产品用内核,还是简化内核)。
> 我这里的产品,还要考虑如何升级这个简化内核,还要考虑万一掉电怎么办,万无一失的升级挺难的,现在是把简化内核放到SPI里面,产品跑SD卡,一旦SD出问题就靠SPI和里面的简化内核救命。

可以理解你的方案,两个不挥发存储器的设计其实还是备份分区的概念啊(要求无备份分区)。

我这个需求确实很恼人的。

杨城

unread,
Mar 6, 2012, 8:48:48 PM3/6/12
to sz...@googlegroups.com

这里有一点可以考虑的是kerne和rootfs在打包后有多大,如果不大可以通过将flash分区,可以系统区和数据区,也可以程序区和备份区。
如果这样都不行,反正升级镜像一定是在RAM中,分块读出flash中的数据与RAM进行校验。

>
>> 其次如果只是需要修改几个配置数据,是否可以将Flash分区来操作,系统区基本不变,只更新数据区,数据区就不使用squahfs了。
>> 如果必须要更新系统,同时又必须要在Linux下。则不要单独写文件系统下的文件,而是将整个镜像重新写入。写入后如下位机无RAM进行校验,就将数据传回PC进行校验。
>> 多说一句,因为Flash有复写次数限制。如果频繁需要重新写一些数据,最好是考虑加入EEPROM保存数据。
>>
>> 之前说的有点"显"的意思,请不要介意
>
>
> 客气了

杨城

X Xiao

unread,
Mar 6, 2012, 10:21:11 PM3/6/12
to sz...@googlegroups.com
1. 杀掉所有无关进程,尽量腾出点内存
2. chroot 到 小型RAMFS(精简版BUSYBOX),直接对FLASH的SQUASHFS根文件系统整体更新
3. 重启
不知道你是否要保留数据分区,或者类似OPENWRT的JFFS2本地改动,如果要稍微麻烦点,但可以做到。

openwrt的sysupgrade可以借鉴,直接升级内核和squashfs:
https://dev.openwrt.org/browser/trunk/package/base-files/files/sbin/sysupgrade

-xxiao

Wick

unread,
Mar 6, 2012, 10:32:00 PM3/6/12
to sz...@googlegroups.com
2012/3/7 X Xiao <fos...@gmail.com>:

> 1. 杀掉所有无关进程,尽量腾出点内存
> 2. chroot 到 小型RAMFS(精简版BUSYBOX),直接对FLASH的SQUASHFS根文件系统整体更新
> 3. 重启
> 不知道你是否要保留数据分区,或者类似OPENWRT的JFFS2本地改动,如果要稍微麻烦点,但可以做到。
>
> openwrt的sysupgrade可以借鉴,直接升级内核和squashfs:
> https://dev.openwrt.org/browser/trunk/package/base-files/files/sbin/sysupgrade

正是我要找的,openwrt能应用也相当有说服力。
多谢。

<snip>

Cheng Renquan

unread,
Mar 6, 2012, 11:00:18 PM3/6/12
to sz...@googlegroups.com, Wick
2012/3/6 Wick <izha...@gmail.com>:

我这里在做不同产品,但同样也是嵌入式板上运行linux要做能防掉电的软件升级,16M的flash分成两半,做成主备交替升级,
squashfs用于提高压缩比存放程序,再ext2/jffs2存数据保存配置文件;升级的时候就是新的squash image 整个写下去

再搜索一下国外的资料发现还有人专为此写了paper在 2005年"Ottawa Linux 文集" 这个会议上
很多观点至今适用: 任何 non atomic upgrade 都是 broken by design; 但做产品都想要节省成本没办法
还是 openwrt 有现成脚本直接用最好了

http://stackoverflow.com/questions/6937592/implementing-an-update-upgrade-system-for-embedded-linux-devices

2 I believe you are looking wrong at the problem - any update which is
non atomic (e.g. dd a file system image, replace files in a directory)
is broken by design - if the power goes off in the middle of an update
the system is a brick and for embedded system, power can go off in the
middle of an upgrade.

I have written a white paper on how to correctly do upgrade/update on
embedded Linux systems. It was presented at OLS. You can find the
paper here: http://www.linuxsymposium.org/archives/OLS/Reprints-2005/ben-yossef-Reprint.pdf

Reply all
Reply to author
Forward
0 new messages