1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| if (target_is_emmc_boot()) { // 如果目标设备是emmc boot(内嵌boot) hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR; // 获取emmc boot镜像首地址 goto continue_boot; // 继续启动 }
ptable = flash_get_ptable(); // 获取分区表 if(!boot_into_recovery) //非recovery模式 { ptn = ptable_find(ptable, "boot"); //获取boot分区 } else { ptn = ptable_find(ptable, "recovery"); // 获取recovery分区 }
if (flash_read(ptn, offset, buf, page_size)) //获取boot镜像 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) //校验boot头 if (hdr->page_size != page_size) //校验boot页大小
/* * Update the kernel/ramdisk/tags address if the boot image header * has default values, these default values come from mkbootimg when * the boot image is flashed using fastboot flash:raw */ update_ker_tags_rdisk_addr(hdr); //读取boot image头,如有默认值则更新kernel、ramdisk、tag地址
/* Get virtual addresses since the hdr saves physical addresses. */ /* 根据物理地址获取虚拟地址 */ hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr)); hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr)); hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask); //获取kernel实际地址 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); // 获取ramdisk实际地址
/* Check if the addresses in the header are valid. */ /* 检查镜像头中的地址有效性*/ if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) || check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE)) //检查设备树地址是否与aboot地址重合
/* Authenticate Kernel */ /* 鉴定内核 */ if(target_use_signed_kernel() && (!device.is_unlocked)) //如果用签名kernel并且设备未被锁 { image_addr = (unsigned char *)target_get_scratch_address(); offset = 0;
dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask); imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);//获取镜像实际地址 if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size)) //检查设备树地址是否与aboot地址重合
imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
bs_set_timestamp(BS_KERNEL_LOAD_START); // 开始加载boot镜像
/* Read image without signature */ /* 读取没有签名的镜像*/ if (flash_read(ptn, offset, (void *)image_addr, imagesize_actual)) bs_set_timestamp(BS_KERNEL_LOAD_DONE); //boot镜像加载完成
offset = imagesize_actual; /* Read signature */ /* 获取boot镜像签名 */ if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size)) verify_signed_bootimg(image_addr, imagesize_actual);
/* Move kernel and ramdisk to correct address */ /* 移动kernel和ramdisk到正确地址*/ memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size); memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size); #if DEVICE_TREE /* Validate and Read device device tree in the "tags_add */ /* 校验并获取设备树*/ if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size)) memmove((void*) hdr->tags_addr, (char *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size); #endif
/* Make sure everything from scratch address is read before next step!*/ if(device.is_tampered) { write_device_info_flash(&device); } #if USE_PCOM_SECBOOT set_tamper_flag(device.is_tampered); #endif } else { offset = page_size;
kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask); ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask); second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
bs_set_timestamp(BS_KERNEL_LOAD_START); // 开始加载boot镜像
if (flash_read(ptn, offset, (void *)hdr->kernel_addr, kernel_actual)) // 获取boot镜像 offset += kernel_actual; if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) //获取ramdisk镜像 offset += ramdisk_actual; bs_set_timestamp(BS_KERNEL_LOAD_DONE); // 结束加载
if(hdr->second_size != 0) { offset += second_actual; /* Second image loading not implemented. */ ASSERT(0); //跳过第二镜像 }
if(hdr->dt_size != 0) { // 如果设备文件存在
/* Read the device tree table into buffer */ if(flash_read(ptn, offset, (void *) dt_buf, page_size)) // 读取设备树分区 table = (struct dt_table*) dt_buf;
if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) //校验设备树分区
table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size); // 获取内存地址
/* Read the entire device tree table into buffer */ if(flash_read(ptn, offset, (void *)table, dt_hdr_size)) // 读取设备树分区
/* Find index of device tree within device tree table */ if(dev_tree_get_entry_info(table, &dt_entry) != 0) //获取设备树地址
/* Validate and Read device device tree in the "tags_add */ if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size)) // 校验设备树地址是否与aboot地址重合
/* Read device device tree in the "tags_add */ if(flash_read(ptn, offset + dt_entry.offset, (void *)hdr->tags_addr, dt_entry.size)) // 获取设备树 }
} continue_boot:
/* TODO: create/pass atags to kernel */
boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr, (const char *)hdr->cmdline, board_machtype(), (void *)hdr->ramdisk_addr, hdr->ramdisk_size); //启动内核 return 0; }
|