有時在工作中會遇到同時使用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就出來了。
好了, 這篇文章就這樣了。