Security Boot手动签章使用参考
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 01/31/2024 | |
2.0 | 05/31/2024 |
1. 概述¶
本文将介绍security boot手动签章每一个阶段的boot image,同时让读者们了解每步签章的含义。完整的Security boot原理和使用流程、以及调试流程和正式流程相关介绍请先参考文档《Security Boot使用参考》。
制作签章系统镜像,建议客户使用security_boot_tools自动处理SDK image包,优点是简单快捷,但是需要依赖提前编译好SDK image包。对于有特殊要求的客户,不想使用security_boot_tools自动签章,则可以参考本文档介绍,手动使用py工具对客户自家制作的系统镜像进行手动签章。
开发阶段通常建议客户先使用调试模式签章镜像,目的是先确认OTP key内容烧录正确,再使用OTP正式模式签章镜像。
制作RSA key和aes Key在文档《Security Boot使用参考》已有详细介绍,本文不再赘述。
1.1 签章工具¶
手动签章的工具分别放在:
- project/image/security_boot_tools/tools/add_ipl_header.py
- 此py是将image进行aes加密、append、sign等操作
- project/image/security_boot_tools/tools/key_proc.py
- 此py是将image进行aes加密、append、sign等操作,里面引用了deal_image.sh和sign_img.sh和pend.bin
- project/image/security_boot_tools/tools/mkimage
- 此工具是将sz压缩后的image,头部加上header数据
- project/image/security_boot_tools/tools/sz/sstar_sz.sh
- 此脚本是将image进行sz压缩,里面调用了sz、szdec、szsplit工具
- project/image/security_boot_tools/tools/unsz/szdec 和 szrestore
- 用于将image进行sz解压缩
2. 签章IPL¶
2.1. OTP正式模式¶
-
插入public key到IPL.bin (如果只签章不加密,使用这个命令)
./key_proc.py --insert --rsa=./public-cust.pem -f ./IPL.bin (生成IPL.cipher.bin)
或者
插入public key和IV值到IPL.bin (如果签章+加密,使用这个命令)
./key_proc.py --insert --rsa=./public-cust.pem --IV=IV.bin -f ./IPL.bin (生成IPL.cipher.bin)
-
改变IPL的header,变成非调试模式,同时anti-rollback的image version为0,脚本参数为:输入文件/输出文件/CID/AUTH/Anti-rollback/Aes_number
./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 0 0 0(生成IPL.cipher2.bin)
-
用上一步骤的输出文件,做AES-CBC加密(如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f ./IPL.cipher.bin(生成IPL.cipher.aes.bin)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher.aes.bin (生成IPL.cipher.aes.sig.bin)
或者
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher.bin (生成IPL.cipher.sig.bin)
2.2. 调试模式¶
-
插入public key到IPL.bin (如果只签章不加密,使用这个命令)
./key_proc.py --insert --rsa=./public-cust.pem -f ./IPL.bin (生成IPL.cipher.bin)
或者
插入public key和IV值到IPL.bin (如果签章+加密,使用这个命令)
./key_proc.py --insert --rsa=./public-cust.pem --IV=IV.bin -f ./IPL.bin (生成IPL.cipher.bin)
-
改变IPL的header,变成调试模式,同时anti-rollback的image version为0,脚本参数为:输入文件/输出文件/CID/AUTH/Anti-rollback/Aes_number
./add_ipl_header.py ./IPL.cipher.bin ./IPL.cipher2.bin 0 1 0 0(生成IPL.cipher2.bin)
-
用上一步骤的输出文件,做AES-CBC加密(如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=./IV.bin --aes=./aesKey128_1.bin -f ./IPL.cipher2.bin (生成IPL.cipher2.aes.bin)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher2.aes.bin (生成IPL.cipher2.aes.sig.bin)
或者
./key_proc.py --sign --rsa=./private-otp.pem -f ./IPL.cipher2.bin (生成IPL.cipher2.sig.bin)
3. 签章IPL_CUST¶
IPL_CUST只支持签章,不支持加密。
-
插入public key到IPL_CUST.bin
./key_proc.py --insert --rsa=./public-image.pem -f ./IPL_CUST.bin (生成IPL_CUST.cipher.bin)
-
改变IPL_CUST的header,变成调试模式(如果是OTP正式模式下,设置为任意值都可),anti-rollback的image version为0,同时设置AES_KEY_NUMBE=0,脚本参数为:输入文件/输出文件/CID/AUTH/Anti-rollback/Aes_number
./add_ipl_header.py IPL_CUST.cipher.bin IPL_CUST.cipher2.bin 0 1 0 1 (生成IPL_CUST.cipher2.bin)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-cust.pem -f ./IPL_CUST.cipher2.bin (生成IPL_CUST.cipher2.sig.bin)
4. 签章UBOOT¶
UBOOT镜像分非压缩和sz压缩两种,根据客户实际使用决定签章步骤。以签章u-boot_spinand.xz.img.bin和签章u-boot_spinand.sz.img.bin为例,实际使用哪个UBOOT镜像由客户实际情况决定。
4.1 签章u-boot_spinand.xz.img.bin¶
-
aes加密 u-boot_spinand.xz.img.bin (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f u-boot_spinand.xz.img.bin (生成u-boot_spinand.xz.img.aes.bin)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./u-boot_spinand.xz.img.aes.bin (生成u-boot_spinand.xz.img.aes.append.bin)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./u-boot_spinand.xz.img.bin (生成u-boot_spinand.xz.img.append.bin)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.xz.img.aes.append.bin (生成u-boot_spinand.xz.img.aes.append.sig.bin)
或者
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.xz.img.append.bin (生成u-boot_spinand.xz.img.append.sig.bin)
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.xz.img.append.sig.bin u-boot_spinand.xz.img.append.sig.bin.sbot (生成u-boot_spinand.xz.img.append.sig.bin.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.xz.img.append.sig.bin u-boot_spinand.xz.img.append.sig.bin.sbot (生成u-boot_spinand.xz.img.append.sig.bin.sbot)
4.2 签章u-boot_spinand.sz.img.bin¶
-
u-boot_spinand.sz.img.bin分成了2份,u-boot_spinand.sz.img.bin_text.sz是data数据,u-boot_spinand.sz.img.bin_header是header数据。将data数据sz解压后,再进行加密验签,最后sz压缩和戴上header数据。
dd if=u-boot_spinand.sz.img.bin of=u-boot_spinand.sz.img.bin_text.sz bs=1 skip=64
dd if=u-boot_spinand.sz.img.bin of=u-boot_spinand.sz.img.bin_header bs=64 count=1
./unsz/szrestore u-boot_spinand.sz.img.bin_text.sz u-boot_spinand.sz.img.bin.xz
./unsz/szdec u-boot_spinand.sz.img.bin.xz u-boot_spinand.sz.img.bin_payload
-
用上一步骤的输出文件,进行aes加密 (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f u-boot_spinand.sz.img.bin_payload (生成u-boot_spinand.sz.img.aes.bin_payload)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./u-boot_spinand.sz.img.aes.bin_payload (生成 u-boot_spinand.sz.img.aes.append.bin_payload)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f u-boot_spinand.sz.img.bin_payload (生成u-boot_spinand.sz.img.append.bin_payload)
-
用上一步骤的输出文件,进行签名
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.sz.img.aes.append.bin_payload (生成u-boot_spinand.sz.img.aes.append.sig.bin_payload)
或者
./key_proc.py --sign --rsa=./private-image.pem -f u-boot_spinand.sz.img.append.bin_payload (生成u-boot_spinand.sz.img.append.sig.bin_payload)
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.sz.img.aes.append.sig.bin_payload u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot (生成u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d u-boot_spinand.sz.img.append.bin_payload u-boot_spinand.sz.img.append.bin_payload.sbot (生成u-boot_spinand.sz.img.append.bin_payload.sbot)
-
用上一步骤的输出文件,进行sz压缩和戴上header数据,最终生成u-boot_spinand.sz.img.bin
./sstar_sz.sh -d u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 u-boot_spinand.sz.img.bin_header)
version="${result%%.*}"
./mkimage -A arm -O u-boot -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d u-boot_spinand.sz.img.aes.append.sig.bin_payload.sbot.sz u-boot_spinand.sz.img.bin
或者
./sstar_sz.sh -d u-boot_spinand.sz.img.append.bin_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 u-boot_spinand.sz.img.bin_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 u-boot_spinand.sz.img.bin_header)
version="${result%%.*}"
./mkimage -A arm -O u-boot -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d u-boot_spinand.sz.img.append.bin_payload.sbot.sz u-boot_spinand.sz.img.bin
5. 签章KERNEL¶
KERNEL镜像分非压缩和sz压缩两种,根据客户实际使用决定签章步骤。以签章uImage.xz和签章uImage.sz为例,实际使用哪个KERNEL镜像由客户实际情况决定。
5.1 签章uImage.xz¶
-
aes加密 uImage.xz (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f uImage.xz (生成uImage.aes.xz)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./uImage.aes.xz (生成uImage.aes.append.xz)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./uImage.xz (生成uImage.append.xz)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-image.pem -f uImage.aes.append.xz (生成uImage.aes.append.sig.xz)
或者
./key_proc.py --sign --rsa=./private-image.pem -f uImage.append.xz (生成uImage.append.sig.xz)
5.2 签章uImage.sz¶
-
uImage.sz分成了2份,uImage.sz_text.sz是data数据,uImage.sz_header是header数据。将data数据sz解压后,再进行加密验签,最后sz压缩和戴上header数据。
dd if=uImage.sz of=uImage.sz_text.sz bs=1 skip=64
dd if=uImage.sz of=uImage.sz_header bs=64 count=1
./unsz/szrestore uImage.sz_text.sz uImage.sz.xz
./unsz/szdec uImage.sz.xz uImage.sz_payload
-
用上一步骤的输出文件,进行aes加密 (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f uImage.sz_payload (生成uImage.aes.sz_payload)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./uImage.aes.sz_payload (生成 uImage.aes.append.sz_payload)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f uImage.sz_payload (生成uImage.append.sz_payload)
-
用上一步骤的输出文件,进行签名
./key_proc.py --sign --rsa=./private-image.pem -f uImage.aes.append.sz_payload (生成uImage.aes.append.sig.sz_payload)
或者
./key_proc.py --sign --rsa=./private-image.pem -f uImage.append.sz_payload (生成uImage.append.sig.sz_payload)
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d uImage.aes.append.sig.sz_payload uImage.aes.append.sig.sz_payload.sbot (生成uImage.aes.append.sig.sz_payload.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d uImage.append.sig.sz_payload uImage.append.sig.sz_payload.sbot (生成uImage.append.sig.sz_payload.sbot)
-
用上一步骤的输出文件,进行sz压缩和戴上header数据,最终生成uImage.sz
./sstar_sz.sh -d uImage.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 uImage.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 uImage.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 uImage.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux-C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d uImage.aes.append.sig.sz_payload.sbot.sz uImage.sz
或者
./sstar_sz.sh -d uImage.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 uImage.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 uImage.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 uImage.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d uImage.append.sig.sz_payload.sbot.sz uImage.sz
6. 签章文件系统¶
注意: 如果文件系统的类型本就是可读写或者会动态变化,例如FWFS,则不会进行签章,下文重点以根文件系统的签章为重点介绍
根文件系统只有为只读属性并且体积足够小能够完整加载到内存中,才能制作签章镜像。如果根文件系统可读可写,或者体积太大无法一次性加载到内存中进行验签,则无法制作签章镜像。
INITRAMFS镜像分非压缩和sz压缩两种,根据客户实际使用决定签章步骤。以签章initramfs.gz.bin和签章initramfs.gz.sz为例,实际使用哪个INITRAMFS镜像由客户实际情况决定。
6.1 签章initramfs.gz¶
-
aes加密 initramfs.gz.bin (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f initramfs.gz.bin (生成initramfs.gz.aes.bin)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./initramfs.gz.aes.bin (生成initramfs.gz.aes.append.bin)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./initramfs.gz.bin (生成initramfs.gz.append.bin)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.aes.append.bin (生成initramfs.gz.aes.append.sig.bin)
或者
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.append.bin (生成initramfs.gz.append.sig.bin )
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.aes.append.sig.bin initramfs.gz.aes.append.sig.bin.sbot (生成initramfs.gz.aes.append.sig.bin.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.append.sig.bin initramfs.gz.append.sig.bin.sbot (生成initramfs.gz.append.sig.bin.sbot)
6.2 签章initramfs.gz.sz¶
-
initramfs.gz.sz分成了2份,initramfs.gz.sz_text.sz是data数据,initramfs.gz.sz_header是header数据。将data数据sz解压后,再进行加密验签,最后sz压缩和戴上header数据。
dd if=initramfs.gz.sz of=initramfs.gz.sz_text.sz bs=1 skip=64
dd if=initramfs.gz.sz of=initramfs.gz.sz_header bs=64 count=1
./unsz/szrestore initramfs.gz.sz_text.sz initramfs.gz.sz.xz
./unsz/szdec initramfs.gz.sz.xz initramfs.gz.sz_payload
-
用上一步骤的输出文件,进行aes加密 (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f initramfs.gz.sz_payload (生成initramfs.gz.aes.sz_payload)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./initramfs.gz.aes.sz_payload (生成 initramfs.gz.aes.append.sz_payload)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f initramfs.gz.sz_payload (生成initramfs.gz.append.sz_payload)
-
用上一步骤的输出文件,进行签名
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.aes.append.sz_payload (生成initramfs.gz.aes.append.sig.sz_payload)
或者
./key_proc.py --sign --rsa=./private-image.pem -f initramfs.gz.append.sz_payload (生成initramfs.gz.append.sig.sz_payload)
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.aes.append.sig.sz_payload initramfs.gz.aes.append.sig.sz_payload.sbot (生成initramfs.gz.aes.append.sig.sz_payload.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d initramfs.gz.append.sz_payload initramfs.gz.append.sz_payload.sbot (生成initramfs.gz.append.sz_payload.sbot)
-
用上一步骤的输出文件,进行sz压缩和戴上header数据,最终生成initramfs.gz.sz
./sstar_sz.sh -d initramfs.gz.aes.append.sig.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 initramfs.gz.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 initramfs.gz.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 initramfs.gz.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d initramfs.gz.aes.append.sig.sz_payload.sbot.sz initramfs.gz.sz
或者
./sstar_sz.sh -d initramfs.gz.append.sz_payload.sbot -b 4
ld_addr=$(hexdump -e '¼ "%02x0x"' -s 16 -n 4 initramfs.gz.sz_header | tac -rs ..)
ep_addr=$(hexdump -e '¼ "%02x0x"' -s 20 -n 4 initramfs.gz.sz_header | tac -rs ..)
result=$(hexdump -v -e '/1 "%_p"' -s 32 -n 32 initramfs.gz.sz_header)
version="${result%%.*}"
./mkimage -A arm -O linux -C lzma2 -a ${ld_addr} -e ${ep_addr} -n ${version} -d initramfs.gz.append.sz_payload.sbot.sz initramfs.gz.sz
注意: initramfs签章后,需要设置uboot bootcmd去验签,通过sigauth命令进行验签,举例如下:
loados nand by_header RAMDISK by_header;sigauth ${loados_addr} 0x21000000;bootm start ${loados_addr};bootm loados;bootm prep;
6.3 签章rootfs.sqfs¶
-
aes加密 rootfs.sqfs (如果只签章不加密,这步骤则省略)
./key_proc.py --encrypt --mode=cbc --IV=IV.bin --aes=./aesKey128_1.bin -f rootfs.sqfs (生成rootfs.sqfs.aes.bin)
-
用上一步骤的输出文件,Append 32字节的数据插入到尾部
./key_proc.py --append --anti=0 --aeskeylen=128 --aeskeynum=1 --mode=cbc --IV=./IV.bin -f ./rootfs.sqfs.aes.bin (生成rootfs.sqfs.aes.append.bin)
或者
./key_proc.py --append --anti=0 --aeskeylen=0 --aeskeynum=0 -f ./rootfs.sqfs (生成rootfs.sqfs)
-
用上一步骤的输出文件,进行签章
./key_proc.py --sign --rsa=./private-image.pem -f rootfs.sqfs.aes.append.bin (生成rootfs.sqfs.aes.append.sig.bin)
或者
./key_proc.py --sign --rsa=./private-image.pem -f rootfs.sqfs.append.bin (生成rootfs.sqfs.append.sig.bin )
-
将上一步骤输入的文件,加入Security_Boot头部
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rootfs.sqfs.aes.append.sig.bin rootfs.sqfs.aes.append.sig.bin.sbot (生成rootfs.sqfs.gz.aes.append.sig.bin.sbot)
或者
mkimage -A arm -C none -a 0 -e 0 -n sbot -d rootfs.sqfs.append.sig.bin rootfs.sqfs.append.sig.bin.sbot (生成rootfs.sqfs.append.sig.bin.sbot)
注意: initramfs签章后,需要设置uboot bootcmd去验签,通过sigauth命令进行验签,举例如下:
setenv bootcmd ' dcache off; loados nand 0x22000000 roofs 0x600000; sigauth 22000000 0x21000000 ; loados nand 0x23000000 KERNEL ${kernel_file_size};sigauth 23000000 0x21000000; dcache on; bootm 0x23000000; loados nand 0x23000000 RECOVERY ${recovery_file_size}; bootm 0x23000000;