以往在烧写内核和FS到nandflash的时候,都是使用串口+UBOOT+TFTP的方式来进行,发现此种烧写方式成功率相当高,几乎不会出错.而且UBOOT在烧写和读取nandflash时,均会自动跳过坏块.这样,只要在kernel加载文件系统的时候,解决了nandflash坏块问题,系统几乎很强壮,不会出现启动到一半死机的情况.
一个系统升级的过程就是将映像文件烧写到nandflash的过程.其实想过系统启动后,通过应用程序来实现,但是此种方式不但费时,还可能还会出现不稳定的情况,所以,通过UBOOT升级是一个很不错的选择.
UBL和UBOOT一般是通过使用JTAG+CCS+NANDWriter烧写的,通过研究NANDWriter源码,烧写UBL和UBOOT时,都会烧写一个头部信息到nandflash,这个头部信息大小是1Pagesize(1页大小),其实只使用到前24个字节,第24字节后的都全部标记为0xff.
UBL头部会烧写到1-3块的第1页(pageNum为0),如果烧写到Block 1失败(块号从0开始),则会烧写到Block 2,以此类推.
UBL实际数据会烧写到UBL头部Block+3块,如UBL头部烧写到Block 2,则UBL实际数据从Block 5开始烧写;
UBOOT头部烧写到8-10块(与UBL头部一样,Block 8烧写失败,烧写到Block 9);
UBOOT实际数据自UBOOT Header Block + 3块开始烧写(如UBOOT头烧写在Block 9 则,从Block 12开始烧写).
上面提到的头部的前24字节的数据,实际为6个32位无符号整数的数据:
第0个整数为幻数(加载程序头时,主要查找该幻数)
第1个整数为程序入口地址
第2个整数为程序共使用了多少页来存储(可使用程序文件大小和nandflash的页大小来进行换算)
第3个整数为程序从哪块开始存储
第4个整数为程序从哪页开始存储(固定为0,即从第一页开始存储)
第5个整数为程序加载地址(程序加载到内存的地址)
<其实UBL和UBOOT程序数据烧写地址可以灵活变动(但要保证数据间不存在覆盖),不一定非要从Header Block + 3块开始烧写(因为Header Block + 3块可能是一个坏块或当需要2块以上来存储数据时,中间不能有坏块),只要在头部中指定好程序所占页数和开始存储的块即可>
UBL/UBOOT/kernel/filesystem均可使用UBOOT来进行升级,只是在升级UBL和UBOOT时,需要根据上述规则升级UBL和UBOOT的头部信息.如果只是单纯的把程序数据烧写到nandflash的指定位置,极有可能会导致系统升级失败,特别是在文件大小发生改变(与旧映像文件相比大了1页以上)的时候.
要让uboot知道用户选择了系统升级操作,需要将用户操作记录到uboot的环境变量,uboot启动并在启动内核前,自动检测环境变量,如果需要升级,则执行升级操作.
在应用层操作uboot的环境变量可参考uboot源码tools/env/fw_env.c
在实际设计过程中,需要考虑升级失败时,恢复原有系统的问题,如在升级FS时,进行了擦除操作,但在烧写时失败,则需要还原原来的系统,这有两种方式可以实现:
1 是多准备1个分区,在设备出厂前就将FS多复制1份到该备份分区,在擦除前设置1个uboot环境变量,要求重启设备后恢复系统,并将该环境变量保存到nandflash(出于此考虑主要是烧写较大文件时,需要的时间长,如果在这期间突然断电,系统再次上电后,可根据该环境变量进行系统恢复,不至于不能启动),然后执行擦除和烧写,升级成功后,再设置环境变量取消恢复系统操作,并将环境变量保存到nand;
2 是在擦除前,将原nandflash数据读入DDR,如果在升级期间出现问题,则恢复原数据(这种升级方式对突然断电是无能为力的);
下面来看看客户端:
ipnc已经实现了上述升级功能,在客户端来说,只需要以下几个简单的步骤即可实现:
1 搭建1个tftp服务器;
2 将升级文件复制到tftp服务器根目录;
3 将升级命令发送到ipnc.
其实这简单中还可以进行取巧.
windows下一般是自带了tftp客户端的,但是,非server版本windows没有自带tftp服务器,而server版本windows在system32/dllcatch目录下有一个tftpd.exe文件,该程序就是一个tftp服务器,不过它是服务应用程序,需要以后台服务的方式来启动.通过以下命令,可很轻松的搭建一个tftp服务器:
expand tftpd.ex_ %windir%\system32\tftpd.exe
del tftpd.ex_
instsrv tftpd %windir%\system32\tftpd.exe
reg add hklm\system\currentcontrolset\services\tftpd\Parameters
reg add hklm\system\currentcontrolset\services\tftpd\Parameters /v Directory /t REG_SZ /d c:\tftproot
md c:\tftproot
net start tftpd
其中tftpd.ex_是一个安装文件,如果没有安装盘,可在baidu搜索,结果有一大把.
instsrv也可网上下载,其实该程序就是一个服务安装工具,我们完全可以在自己的升级程序中实现该程序的功能(因为比较简单).