捣鼓openwrt不死bootloader (2)—-兼容sdk固件

  • Post author:
  • Post category:其他


有时在工作中会遇到同时使用openwrt和SDK固件的情况, 这样就会出现使用麻烦, 烧砖的风险也大大增加, 那么有没有什么办法能做到boot为一个, 以后也尽可能不改变呢, 网上也有,比如openwrt社区论坛的大H的不死bootloader。 但是他的不开源, 无法做到定制化,比如说我们的flash有16M的,也有8M的,也有4M等等,这样就制约了我们的工作,看来还是得自己来弄了。

要做到兼容就得分析它们的不同之处, 如何分析呢?

一、 不管他的,直接烧录SDK进入不死bootloader, 看看什么情况。

哈哈~~~~, 这个情况呢,当然是跑死了。。。。。。。情况是这样的:

Booting image at: 0x9F020000

   Image name:   魗ZU迪Linux Ke
   Image type:   MIPS Linux Kernel Image (lzma compressed)
   Data size:    911511324 Bytes = 869.3 MB
   Load address: 0x06A4B3F7
   Entry point:  0xC5148195

Uncompressing kernel image... ## Error: LZMA error num: 1

## Error: failed to execute 'bootcmd'!

看到了吧, 首先读到的头信息都不正确,当然跑不起来了。 那么我们就要去看看SDK的头和openwrt的文件头信息有什么不同。

SDK的是这样的:

typedef struct image_header {
    uint32_t    ih_magic;           /* Image Header Magic Number    */
    uint32_t    ih_hcrc;            /* Image Header CRC Checksum    */
    uint32_t    ih_time;            /* Image Creation Timestamp     */
    uint32_t    ih_size;            /* Image Data Size              */
    uint32_t    ih_load;            /* Data  Load  Address          */
    uint32_t    ih_ep;              /* Entry Point Address          */
    uint32_t    ih_dcrc;            /* Image Data CRC Checksum      */
    uint8_t     ih_os;              /* Operating System             */
    uint8_t     ih_arch;            /* CPU architecture             */
    uint8_t     ih_type;            /* Image Type                   */
    uint8_t     ih_comp;            /* Compression Type             */
    uint8_t     ih_name[IH_NMLEN];  /* Image Name                   */
} image_header_t;

openwrt的是这样的:

/*
 * TAG for downloadable image (kernel plus file system)
 * integer in the structure is stored in Network-Byte order (BIG-endian)
 */
typedef struct _tplink_image_header_t {
    unsigned long   tagVersion;
    char            signiture_1[SIG_LEN];               // text line for company info
    char            signiture_2[SIG_LEN_2];             // additional info (can be version number)
    char            chipId[CHIP_ID_LEN];                // chip id
    char            boardId[BOARD_ID_LEN];              // board id
    unsigned long   productId;                          // product id
    unsigned long   productVer;                         // product version
    unsigned long   reserved1;                          // reserved for future

    unsigned char   imageValidationToken[TOKEN_LEN];    // image validation token - md5 checksum
    unsigned char   kernelValidationToken[TOKEN_LEN];   // kernel+tag validation token - md5 checksum

    unsigned long   kernelTextAddr;                     // text section address of kernel
    unsigned long   kernelEntryPoint;                   // entry point address of kernel
        
    unsigned long   totalImageLen;                      // the sum of kernelLen+rootfsLen+tagLen

    unsigned long   kernelAddress;                      // starting address (offset from the beginning of FILE_TAG) of kernel image      
    unsigned long   kernelLen;                          // length of kernel image

    unsigned long   rootfsAddress;                      // starting address (offset) of filesystem image
    unsigned long   rootfsLen;                          // length of filesystem image

    unsigned long   bootloaderAddress;                  // starting address (offset) of boot loader image
    unsigned long   bootloaderLen;                      // length of boot loader image
    
} tplink_image_header_t;

看到了吧, 差异还是蛮大的。

肿么办,现在? 我想既然两个不一样, 那么这两个头信息我都去试一遍不就得了吗。 那好吧, 但是, 现在问题来了, 我怎么知道他们谁是谁啊!!!!!!

不急, 我们先把他们的头信息都读出来, 看看那些是固定的,就比较他们就行了, 经过分析发现openwrt的头结构体中fileTag->signiture_1是OpenWrt, 而SDK肯定是没有的, 那好就先读取这个信息好了。

如果信息对, 它就按openwrt的正常流程跑就好了。 如果这个信息不对就立马换SDK的结构体去解析数据, 要是解析错误,那就直接报错好了。

到此一个兼容SDK的不死bootloader就出来了。

好了, 这篇文章就这样了。



版权声明:本文为yqj2011原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。