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

              有時在工作中會遇到同時使用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就出來了。


好了, 這篇文章就這樣了。



   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章