上一篇还有bootm_load_os没讲,这个方法主要就是对内核镜像解压
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
uint8_t comp = os.comp; //压缩格式
ulong load = os.load; //加载地址
ulong blob_start = os.start;
//blob=bootloader object起始地址
ulong blob_end = os.end; //blob结束地址
ulong image_start = os.image_start; //镜像起始地址
ulong image_len = os.image_len; //镜像长度
ulong image_end;
const char *type_name = genimg_get_type_name (os.type); //镜像类型
int boot_sp;
__asm__ __volatile__(
"mov %0, sp\n"
:"=r"(boot_sp)
:
:"cc"
);
/* Check whether kernel zImage overwrite uboot,
* which will lead to kernel boot fail. */
image_end = load + image_len;
//检查镜像是否覆盖了uboot引导
/* leave at most 32KByte for move image stack */
boot_sp -= BOOTM_STACK_GUARD;
//将栈顶指针后移,镜像栈需要32K
if( !((load > _bss_end) || (image_end < boot_sp)) ) {
printf("\nkernel image will overwrite uboot! kernel boot fail!\n");
return BOOTM_ERR_RESET;
}
switch (comp) { //选择解压格式
case IH_COMP_NONE: //未压缩
if (load == blob_start || load == image_start) {
printf (" XIP %s ... ", type_name);
} else { //是否需要移动镜像
printf (" Loading %s ... ", type_name);
memmove_wd ((void *)load, (void *)image_start,
image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
break;
#ifdef CONFIG_GZIP
case IH_COMP_GZIP: //gzip解压
printf (" Uncompressing %s ... ", type_name);
if (gunzip ((void *)load, unc_len,
(uchar *)image_start, &image_len) != 0) {
puts ("GUNZIP: uncompress, out-of-mem or overwrite error "
"- must RESET board to recover\n");
if (boot_progress)
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}
*load_end = load + image_len;
break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
case IH_COMP_BZIP2: //bzip2解压
printf (" Uncompressing %s ... ", type_name);
/*
* If we've got less than 4 MB of malloc() space,
* use slower decompression algorithm which requires
* at most 2300 KB of memory.
*/
int i = BZ2_bzBuffToBuffDecompress ((char*)load,
&unc_len, (char *)image_start, image_len,
CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf ("BUNZIP2: uncompress or overwrite error %d "
"- must RESET board to recover\n", i);
if (boot_progress)
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}
*load_end = load + unc_len;
break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
case IH_COMP_LZMA: //lzma解压
printf (" Uncompressing %s ... ", type_name);
int ret = lzmaBuffToBuffDecompress(
(unsigned char *)load, &unc_len,
(unsigned char *)image_start, image_len);
if (ret != SZ_OK) {
printf ("LZMA: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
show_boot_progress (-6);
return BOOTM_ERR_RESET;
}
*load_end = load + unc_len;
break;
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
case IH_COMP_LZO: //lzo解压
printf (" Uncompressing %s ... ", type_name);
int ret = lzop_decompress((const unsigned char *)image_start,
image_len, (unsigned char *)load,
&unc_len);
if (r