Web升级框架 - awokezhou/LinuxPage GitHub Wiki

概述

本文记录嵌入式Linux设备通过Web升级的一种设计框架,包括前端文件上载控件、HTTP multipart/form-data请求、升级文件制作、FLASH分区和MTD

前端文件上载控件

前端代码上传文件的写法如下

<input type="file">

这种写法的文件上载控件样式为原始样式,不美观,不推荐。这里推荐一种基于Bootstrap的文件上载控件方法。

首先使用style="display:none"将原本的文件上载控件屏蔽,

<input type="file" id="test_file" name"test_file" style="display:none">

然后使用Bootstrap的联合表单控件,可以将一个输入框和一个按钮组合,将按钮的onclick事件绑定到文件上载控件的click上

<input type="text" class="span3" id="appendedInputButton" ms-duplex="xxx_cfg.test_file">
<button type="button" class="btn" onclick="$('input[id=test_file]').click();">文件选择</button>

multipart/form-data请求

升级文件的上传,使用的是HTTP协议中的multipart/form-data请求。HTTP协议规定的请求方法有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE,multipart/form-data是多个POST请求的组合体

HTTP表单中如果在Content-Type中的内容是multipart/form-data,表明表单后跟有附件,此时Content-Type格式为

Content-Type: multipart/form-data; boundary=${bound}      

其中${bound} 是一个占位符,代表自己规定的分割符,其作用是如果附件有多个,用这个分隔符来分割。分隔符格式可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容

在前端代码中,此属性填写在<form>表单中

<form id="test_form" name="test_form" enctype="multipart/form-data">
    ... ...
    <input="file" ...>
    <input="test" ...>
    <button type="button" ...>
    ... ...
</form>

在js代码中,调用<form>的submit方法,即可让浏览器发送包含选择文件为附件的HTTP POST请求报文,Server端进行解析和下载,完成文件传输工作

dialog.confirm(upgrade_lang, function(result){
    var options = {
        type: 'post',
        url: "xxx" + + $.param(
            ...,
        ),
        cache:false,
    }
    $("#test_form").ajaxSubmit(options);
});

升级文件制作

一般的嵌入式Linux系统,升级文件的内容大致包括uboot、kernel、romfs和usrconfg等内容,升级文件形式的两种:kernel+romfs+usrconfg[upgrade.bin],uboot+kernel+romfs+usrconfig[upgrade_boot.bin]

  • uboot编译生成uboot.bin,这就是升级文件中uboot的部分
  • romfs的形式有两种,一种是由专门的工具编译生成二进制文件,一种是将其编译进kernel,作为kernel的一部分。如果是后者,需要在kernel的make menuconfig中开启功能
  • 编译kernel生成镜像文件zImage或者uImage
  • 最后通过一个mkimage或者bulidImage工具,将以上生成文件打包,并在开头添加一些私有信息,如软件版本号等,还有CRC校验

FLASH分区和MTD操作

升级最终操作的是设备上的存储介质,将升级文件的内容写入或覆盖到非易失存储介质上,然后reboot。常用的介质是NAND FLASH、NOR FLASH和SPI FLASH,这几种FLASH的优缺点网上有很多说明

FLASH分区

Linux系统上电后,启动顺序为硬件boot->bootloader->kernel->romfs->init->application,比如uboot要加载kernel,它必须明确的知道kernel的启动地址在哪里。一环一环的启动过程,地址都必须非常明确,这就要求对FLASH的分区有一个详细的规划,从起始地址开始,到哪里的多大空间内是什么,再往后多少多大的空间又是什么,都要规划清楚。这个规划图,uboot里和kernel都有,并且他们要保持一致。

MTD

Linux MTD架构专门用于FLASH设备的一种框架,与FLASH分区相结合,抽象出来的/dev/mtd0 mtd1...等设备,和FLASH分区一一对应,在应用层对这些设备进行写操作,会进入这些设备驱动的write操作中,其实质就是先对该设备的空间先进行erase操作,再进行块写操作,以完成升级

⚠️ **GitHub.com Fallback** ⚠️