一般来说要解包固件都很简单,但是要对固件进行修改并重新刷回设备就有一定的难度了。以下是修改固件并刷回设备的方法。
解包固件
本例:dcs932l_v1.14.04.bin,先用binwalk分析下它的结构:



结构很明显,U-Boot加上uImage头加上lzma打包的内核系统。简单的结构图如下:

ok,结构分析完了,现在可以解包固件做点小修改再进行打包了。解包一条命令搞定:
binwalk -Me dcs932l_v1.14.04.bin #如果提示权限出错加上参数:--run-as=root
进入文件系统目录,根据自己需要修改文件,打包成cpio压缩文件:
find . | cpio -H newc -o > ../initrd.cpio
再用lzma进行压缩,可在这里下载对应版本的lzma sdk,注意原固件的lzma压缩指定了字典大小,我们需要使用和它一致的字典大小,用-d参数指定字典大小:
./lzma e initrd.cpio initrd.cpio.lzma -d20
截取内核文件系统前的数据再拼接到我们的文件系统前:
dd if=50040 of=kernelHead bs=1 count=4038656
cp ./kernelHead ./kernel
cat initrd.cpio.lzma >> kernel
再对内核进行压缩:
./lzma e ./kernel ./kernel.lzma -d25
截取uImage头拼接到内核压缩文件前:
dd if=dcs of=uImageHeader bs=1 count=64
cp uImageHeader uImage
cat kernel.lzma >> uImage
注意uImage头这里是有CRC验证的,我们需要自己计算一下CRC校验和并修改uImage头的信息。WinHex打开,下图圈起来的几位分别是header CRC,image大小和data CRC:

先计算data CRC,选中uImage头之后的部分,在Tools->Compute Hash中选择CRC32进行计算:
把data CRC修改为我们计算的值,同时填上image大小的值:
之后计算header CRC的值,把原来的值都用00来覆盖再计算就行了:
当然,也有不需要手动改CRC的方法。在ubuntu下安装u-boot-tools,再用mkimage命令就可以自动生成uImage头:
sudo apt-get install u-boot-tools
mkimage -A MIPS -O linux -T kernel -C lzma -a 0x80000000 -e 0x803B8000 -n "Linux Kernel Image" -d kernel.lzma uImage
mkimage各参数信息如下:
-A ==> set architecture to 'arch' // 用于指定CPU类型
-O ==> set operating system to 'os' // 用于指定操作系统
-T ==> set image type to 'type' // 用于指定image类型
-C ==> set compression type 'comp' // 指定压缩类型
-a ==> set load address to 'addr' (hex) // 指定image的加载地址
-e ==> set entry point to 'ep' (hex) // 指定内核的入口地址
-n ==> set image name to 'name' // image在头结构中的命名
-d ==> use image data from 'datafile' // 无头信息的image文件名
-x ==> set XIP (execute in place) // 设置执行位置
如果你能通过TTL进设备U-Boot的话固件打包到这一步就行了,如果要通过web界面更新固件就需要再加上前面的一段U-Boot了,这里不再赘述。
烧录固件
启动设备,在串行界面可以看到打印如下信息:
U-Boot 1.1.3
Board: Ralink APSoC DRAM: 32 MB
relocate_code Pointer at: 81fac000
config usb..
Set info->start[0]=BF000000
flash_protect ON: from 0xBF000000 to 0xBF021767
flash_protect ON: from 0xBF030000 to 0xBF030FFF
*** Warning - bad CRC, using default environment
============================================
Ralink UBoot Version: 3.5.2.0
--------------------------------------------
ASIC 3052_MP2 (Port5<->None)
DRAM component: 256 Mbits SDR
DRAM bus: 16 bit
Total memory: 32 MBytes
Flash component: NOR Flash
============================================
icache: sets:256, ways:4, linesz:32 ,total:32768
dcache: sets:128, ways:4, linesz:32 ,total:16384
##### The CPU freq = 320 MHZ ####
estimate memory size =32 Mbytes
Signature: DCS-930 932L Release 1.11 (2011-05-31)
Please choose the operation:
1: Load system code to SDRAM via TFTP.
2: Load system code then write to Flash via TFTP.
3: Boot system code via Flash (default).
4: Entr boot command line interface.
7: Load Boot Loader code then write to Flash via Serial.
9: Load Boot Loader code then write to Flash via TFTP.
这里我们选择1,通过TFTP写入系统固件到内存中,不要刷到flash里,不然刷错固件就凉了。搭建TFTP服务器的过程这里就不赘述了。
1: System Load Linux to SDRAM via TFTP.
Please Input new ones /or Ctrl-C to discard
Input device IP (192.168.1.1) ==:192.168.0.100
Input server IP (192.168.1.100) ==:192.168.0.103
Input Linux Kernel filename () ==:uImage
设备从tftp服务器上下载完固件后就会自动启动系统了:
