有时在工作中会遇到同时使用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就出来了。
好了, 这篇文章就这样了。