SmartAudio/lichee/brandy/u-boot-2011.09/common/cmd_boota.c

184 lines
5.1 KiB
C
Raw Permalink Normal View History

2018-07-13 01:31:50 +00:00
/*
* (C) Copyright 2007-2011
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
* Tom Cubie <tangliang@allwinnertech.com>
*
* Boot an image which is generated by android mkbootimg tool
*
* (C) Copyright 2000-2003
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Misc boot support
*/
#include <common.h>
#include <command.h>
#include <net.h>
#include <sunxi_board.h>
#ifdef CONFIG_CMD_BOOTA
#include <fastboot.h>
#ifdef CONFIG_SUNXI_SECURE_SYSTEM
#include <sunxi_efuse.h>
#endif
int __do_sunxi_boot_signature(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
{
return 0;
}
int do_sunxi_boot_signature(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
__attribute__((weak, alias("__do_sunxi_boot_signature")));
static unsigned char boot_hdr[512];
extern int do_boota_linux (struct fastboot_boot_img_hdr *hdr);
DECLARE_GLOBAL_DATA_PTR;
void * memcpy2(void * dest,const void * src,__kernel_size_t n)
{
if (src == dest)
return dest;
if (src < dest) {
if (src + n > dest) {
memcpy((void*) (dest + (dest - src)), dest, src + n - dest);
n = dest - src;
}
memcpy(dest, src, n);
} else {
memcpy(dest, src, n);
}
return dest;
}
int do_boota (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong addr;
unsigned kaddr, raddr;
#ifdef CONFIG_SUNXI_SECURE_SYSTEM
char efuse_hash[32] , all_zero[32];
int ret;
#endif
if (argc < 2)
return cmd_usage(cmdtp);
addr = simple_strtoul(argv[1], NULL, 16);
struct fastboot_boot_img_hdr *fb_hdr = (struct fastboot_boot_img_hdr *)addr;
image_header_t *hdr =(image_header_t *)(addr + CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE);
/* save the image header somewhere */
memcpy(boot_hdr, (void*) addr, sizeof(*hdr));
if (memcmp(fb_hdr->magic, FASTBOOT_BOOT_MAGIC, 8)) {
puts("boota: bad boot image magic, maybe not a boot.img?\n");
return 1;
}
#ifdef DEBUG
printf("---------------------\n");
printf("kernel size: 0x%x \n", fb_hdr->kernel_size);
printf("kernel addr: 0x%x \n", fb_hdr->kernel_addr);
printf("ramdisk size: 0x%x \n", fb_hdr->ramdisk_size);
printf("ramdisk addr: 0x%x \n", fb_hdr->ramdisk_addr);
printf("second size: 0x%x \n", fb_hdr->second_size);
printf("second addr: 0x%x \n", fb_hdr->second_addr);
printf("name: %s\n", fb_hdr->name);
printf("cmdline: %s\n", fb_hdr->cmdline);
#endif
kaddr = addr + fb_hdr->page_size;
raddr = kaddr + ALIGN(fb_hdr->kernel_size, fb_hdr->page_size);
#ifdef DEBUG
printf("moving kernel from %x to: %x, size 0x%x\n", kaddr, fb_hdr->kernel_addr, fb_hdr->kernel_size);
printf("moving ramdisk from %x to: %x, size 0x%x\n", raddr, fb_hdr->ramdisk_addr, fb_hdr->ramdisk_size);
#endif
//memmove((void*) fb_hdr->kernel_addr, (const void *)kaddr, fb_hdr->kernel_size);
//memmove((void*) fb_hdr->ramdisk_addr, (const void *)raddr, fb_hdr->ramdisk_size);
memcpy2((void*) fb_hdr->kernel_addr, (const void *)kaddr, fb_hdr->kernel_size);
memcpy2((void*) fb_hdr->ramdisk_addr, (const void *)raddr, fb_hdr->ramdisk_size);
/* add code for signature */
#ifdef CONFIG_SUNXI_SECURE_SYSTEM
if(gd->securemode)
{
unsigned int total_len = raddr + ALIGN(fb_hdr->ramdisk_size, fb_hdr->page_size) - addr;
printf("total_len=%d\n", total_len);
//Ϊ<><CEAA>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9A3AC><EFBFBD><EFBFBD>֪<EFBFBD><D6AA><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ret = sunxi_verify_signature((void *)addr, total_len, argv[2]);
setenv("verifiedbootstate", "green");
if(ret)
{
printf("boota: verify the %s failed\n", argv[2]);
setenv("verifiedbootstate", "red");
printf("start to display warnings.bmp\n");
sunxi_bmp_display("warnings.bmp");
}
memset(efuse_hash, 0, 32);
ret = sunxi_efuse_read("rotpk", efuse_hash);
if(ret)
{
printf("read efuse rotpk failed\n");
}
else
{
printf("read efuse rotpk successed\n");
sunxi_dump(efuse_hash, 32);
}
memset(all_zero, 0, 32);
if(memcmp(all_zero, efuse_hash,32 ) ){
printf("rotpk has been burn to efuse\n");
setenv("sunxi_rotpk", "true");
}
else{
printf("rotpk efuse is empty\n");
setenv("sunxi_rotpk", "flase");
}
}
#else
do_sunxi_boot_signature(NULL, 0, 0, NULL);
#endif
tick_printf("ready to boot\n");
do_boota_linux(fb_hdr);
puts("Boot linux failed, control return to monitor\n");
return 0;
}
U_BOOT_CMD(
boota, 3, 1, do_boota,
"boota - boot android bootimg from memory\n",
"<addr>\n - boot application image stored in memory\n"
"\t'addr' should be the address of boot image which is kernel+ramdisk.img\n"
);
#endif