load_image.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <stdlib.h>
  32. #include <sys/types.h>
  33. #include <stdint.h>
  34. #include <video.h>
  35. #include <platform/partition.h>
  36. #include <platform/mt_typedefs.h>
  37. #include <platform/boot_mode.h>
  38. #include <platform/mt_reg_base.h>
  39. #include <bootimg.h>
  40. #include <platform/errno.h>
  41. #include <platform/verified_boot.h>
  42. #include <printf.h>
  43. #include <string.h>
  44. #include <malloc.h>
  45. #include <platform/mt_gpt.h>
  46. #include <platform/sec_status.h>
  47. #include <platform/mtk_key.h>
  48. #include <target/cust_key.h>
  49. #include <part_interface.h>
  50. // #include <block_generic_interface.h> // for mt_part_get_device()
  51. #include <storage_api.h>
  52. #include <target.h> // for target_get_scratch_address()
  53. #include <verified_boot_common.h>
  54. #include <boot_opt.h>
  55. #include <odm_mdtbo.h>
  56. #define MODULE_NAME "LK_BOOT"
  57. // From proinfo which is defined in PC side META tool spmeta.h.
  58. #define PARTITION_SIZE (64 + 40 + 6 + 6)
  59. //*********
  60. //* Notice : it's kernel start addr (and not include any debug header)
  61. unsigned int g_kmem_off = 0;
  62. //*********
  63. //* Notice : it's rootfs start addr (and not include any debug header)
  64. unsigned int g_rmem_off = 0;
  65. unsigned int g_bimg_sz = 0;
  66. unsigned int g_rcimg_sz = 0;
  67. int g_kimg_sz = 0;
  68. int g_rimg_sz = 0;
  69. #define DTBO_IMG_ALIGN_SZ (16)
  70. extern struct bootimg_hdr *g_boot_hdr;
  71. extern bool cmdline_append(const char *append_string);
  72. extern void mtk_wdt_restart(void);
  73. #define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000) >> 24) | \
  74. (( (uint32)(A) & 0x00ff0000) >> 8) | \
  75. (( (uint32)(A) & 0x0000ff00) << 8) | \
  76. (( (uint32)(A) & 0x000000ff) << 24))
  77. int verified_boot_flow(char *part_name, char *target)
  78. {
  79. int ret = 0;
  80. unsigned int img_vfy_time = 0;
  81. int lock_state = 0;
  82. /* if MTK_SECURITY_SW_SUPPORT is not defined, boot state is always green */
  83. #ifdef MTK_SECURITY_SW_SUPPORT
  84. /* please refer to the following website for verified boot flow */
  85. /* http://source.android.com/devices/tech/security/verifiedboot/verified-boot.html */
  86. ret = sec_query_device_lock(&lock_state);
  87. if (ret) {
  88. g_boot_state = BOOT_STATE_RED;
  89. goto _end;
  90. }
  91. if (DEVICE_STATE_LOCKED == lock_state) {
  92. if (g_boot_state == BOOT_STATE_GREEN)
  93. goto _end;
  94. sec_clear_pubk();
  95. g_boot_state = BOOT_STATE_GREEN;
  96. img_vfy_time = get_timer(0);
  97. ret = android_verified_boot(part_name, target);
  98. if (0 == ret)
  99. g_boot_state = BOOT_STATE_GREEN;
  100. else if (ERR_NOT_OEM_KEY == ret)
  101. g_boot_state = BOOT_STATE_YELLOW;
  102. else {
  103. g_boot_state = BOOT_STATE_RED;
  104. sec_clear_pubk();
  105. }
  106. dprintf(INFO, "[SBC] img vfy(%d ms)\n", (unsigned int)get_timer(img_vfy_time));
  107. } else if (DEVICE_STATE_UNLOCKED == lock_state)
  108. g_boot_state = BOOT_STATE_ORANGE;
  109. else /* unknown lock state*/
  110. g_boot_state = BOOT_STATE_RED;
  111. #endif //MTK_SECURITY_SW_SUPPORT
  112. _end:
  113. ret = print_boot_state();
  114. if (ret)
  115. return ret;
  116. if (target == NULL)
  117. ret = show_warning("UNKNOWN");
  118. else
  119. ret = show_warning(target);
  120. if (ret)
  121. return ret;
  122. ret = set_boot_state_to_cmdline();
  123. if (ret)
  124. return ret;
  125. return ret;
  126. }
  127. static int mboot_common_load_part_info(char *part_name,
  128. part_hdr_t *part_hdr)
  129. {
  130. long len;
  131. // part_t *part;
  132. //***************
  133. //* read partition header
  134. //*
  135. len = partition_read(part_name, 0, (uchar *)part_hdr, sizeof(part_hdr_t));
  136. if (len < 0) {
  137. dprintf(CRITICAL, "[%s] %s partition read error. LINE: %d\n", MODULE_NAME,
  138. part_name, __LINE__);
  139. return -1;
  140. }
  141. dprintf(CRITICAL, "\n=========================================\n");
  142. dprintf(CRITICAL, "[%s] %s magic number : 0x%x\n", MODULE_NAME, part_name,
  143. part_hdr->info.magic);
  144. part_hdr->info.name[31] = '\0'; //append end char
  145. dprintf(CRITICAL, "[%s] %s name : %s\n", MODULE_NAME, part_name,
  146. part_hdr->info.name);
  147. dprintf(CRITICAL, "[%s] %s size : %d\n", MODULE_NAME, part_name,
  148. part_hdr->info.dsize);
  149. dprintf(CRITICAL, "=========================================\n");
  150. //***************
  151. //* check partition magic
  152. //*
  153. if (part_hdr->info.magic != PART_MAGIC) {
  154. dprintf(CRITICAL, "[%s] %s partition magic error\n", MODULE_NAME, part_name);
  155. return -1;
  156. }
  157. //***************
  158. //* check partition name
  159. //*
  160. if (strncasecmp(part_hdr->info.name, part_name, sizeof(part_hdr->info.name))) {
  161. dprintf(CRITICAL, "[%s] %s partition name error\n", MODULE_NAME, part_name);
  162. return -1;
  163. }
  164. //***************
  165. //* check partition data size
  166. //*
  167. if (part_hdr->info.dsize > partition_get_size_by_name(part_name)) {
  168. dprintf(CRITICAL, "[%s] %s partition size error\n", MODULE_NAME, part_name);
  169. return -1;
  170. }
  171. return 0;
  172. }
  173. /**********************************************************
  174. * Routine: mboot_common_load_part
  175. *
  176. * Description: common function for loading image from nand flash
  177. * this function is called by
  178. * (1) 'mboot_common_load_logo' to display logo
  179. *
  180. **********************************************************/
  181. int mboot_common_load_part(char *part_name, unsigned long addr)
  182. {
  183. long len;
  184. part_hdr_t *part_hdr;
  185. part_hdr = (part_hdr_t *)malloc(sizeof(part_hdr_t));
  186. if (!part_hdr)
  187. return -ENOMEM;
  188. len = mboot_common_load_part_info(part_name, part_hdr);
  189. if (len < 0) {
  190. len = -EINVAL;
  191. goto exit;
  192. }
  193. //****************
  194. //* read image data
  195. //*
  196. dprintf(INFO, "read the data of %s\n", part_name);
  197. len = partition_read(part_name, sizeof(part_hdr_t), (uchar *)addr,
  198. (size_t)part_hdr->info.dsize);
  199. if (len < 0) {
  200. len = -EIO;
  201. goto exit;
  202. }
  203. exit:
  204. if (part_hdr)
  205. free(part_hdr);
  206. return len;
  207. }
  208. /**********************************************************
  209. * Routine: mboot_common_load_logo
  210. *
  211. * Description: function to load logo to display
  212. *
  213. **********************************************************/
  214. int mboot_common_load_logo(unsigned long logo_addr, char *filename)
  215. {
  216. int ret;
  217. #if (CONFIG_COMMANDS & CFG_CMD_FAT)
  218. long len;
  219. #endif
  220. #if (CONFIG_COMMANDS & CFG_CMD_FAT)
  221. len = file_fat_read(filename, (unsigned char *)logo_addr, 0);
  222. if (len > 0)
  223. return (int)len;
  224. #endif
  225. ret = mboot_common_load_part("logo", logo_addr);
  226. return ret;
  227. }
  228. /**********************************************************
  229. * Routine: mboot_android_check_img_info
  230. *
  231. * Description: this function is called to
  232. * (1) check the header of kernel / rootfs
  233. *
  234. * Notice : this function will be called by 'mboot_android_check_bootimg_hdr'
  235. *
  236. **********************************************************/
  237. int mboot_android_check_img_info(char *part_name, part_hdr_t *part_hdr)
  238. {
  239. //***************
  240. //* check partition magic
  241. //*
  242. if (part_hdr->info.magic != PART_MAGIC) {
  243. dprintf(CRITICAL, "[%s] %s partition magic not match\n", MODULE_NAME,
  244. part_name);
  245. return -1;
  246. }
  247. //***************
  248. //* check partition name
  249. //*
  250. if (strncasecmp(part_hdr->info.name, part_name, sizeof(part_hdr->info.name))) {
  251. dprintf(CRITICAL, "[%s] %s partition name not match\n", MODULE_NAME, part_name);
  252. return -1;
  253. }
  254. dprintf(CRITICAL, "\n=========================================\n");
  255. dprintf(CRITICAL, "[%s] %s magic number : 0x%x\n", MODULE_NAME, part_name,
  256. part_hdr->info.magic);
  257. dprintf(CRITICAL, "[%s] %s size : 0x%x\n", MODULE_NAME, part_name,
  258. part_hdr->info.dsize);
  259. dprintf(CRITICAL, "=========================================\n");
  260. //***************
  261. //* return the image size
  262. //*
  263. return part_hdr->info.dsize;
  264. }
  265. /**********************************************************
  266. * Routine: mboot_android_check_bootimg_hdr
  267. *
  268. * Description: this function is called to
  269. * (1) 'read' the header of boot image from nand flash
  270. * (2) 'parse' the header of boot image to obtain
  271. * - (a) kernel image size
  272. * - (b) rootfs image size
  273. * - (c) rootfs offset
  274. *
  275. * Notice : this function must be read first when doing nand / msdc boot
  276. *
  277. **********************************************************/
  278. static int mboot_android_check_bootimg_hdr( char *part_name,
  279. struct bootimg_hdr *boot_hdr)
  280. {
  281. long len;
  282. int ret = 0;
  283. u64 addr;
  284. //**********************************
  285. // TODO : fix pg_sz assignment
  286. //**********************************
  287. unsigned int pg_sz = 2 * 1024;
  288. addr = partition_get_offset_by_name(part_name);
  289. //***************
  290. //* read partition header
  291. //*
  292. dprintf(CRITICAL, "part page addr is 0x%llx\n", addr);
  293. len = partition_read(part_name, 0, (uchar *) boot_hdr, sizeof(struct bootimg_hdr));
  294. if (len < 0) {
  295. dprintf(CRITICAL, "[%s] %s boot image header read error. LINE: %d\n",
  296. MODULE_NAME, part_name, __LINE__);
  297. return -1;
  298. }
  299. dprintf(CRITICAL,
  300. "\n============================================================\n");
  301. dprintf(CRITICAL, "[%s] Android Partition Name : %s\n",
  302. MODULE_NAME, part_name);
  303. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - OS Version : 0x%08X\n",
  304. MODULE_NAME, boot_hdr->os_version);
  305. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Kernel Size : 0x%08X\n",
  306. MODULE_NAME, boot_hdr->kernel_sz);
  307. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Kernel Address : 0x%08X\n",
  308. MODULE_NAME, boot_hdr->kernel_addr);
  309. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Rootfs Size : 0x%08X\n",
  310. MODULE_NAME, boot_hdr->ramdisk_sz);
  311. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Rootfs Address : 0x%08X\n",
  312. MODULE_NAME, boot_hdr->ramdisk_addr);
  313. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Tags Address : 0x%08X\n",
  314. MODULE_NAME, boot_hdr->tags_addr);
  315. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Page Size : 0x%08X\n",
  316. MODULE_NAME, boot_hdr->page_sz);
  317. dprintf(CRITICAL, "[%s] Android Boot IMG Hdr - Command Line : %s\n",
  318. MODULE_NAME, boot_hdr->cmdline);
  319. dprintf(CRITICAL,
  320. "============================================================\n");
  321. //***************
  322. //* check partition magic
  323. //*
  324. if (strncmp((char const *)boot_hdr->magic, BOOTIMG_MAGIC, BOOTIMG_MAGIC_SZ) != 0) {
  325. dprintf(CRITICAL, "[%s] boot image header magic error\n", MODULE_NAME);
  326. return -1;
  327. }
  328. pg_sz = boot_hdr->page_sz;
  329. //***************
  330. //* follow bootimg.h to calculate the location of rootfs
  331. //*
  332. if (len != -1) {
  333. unsigned int k_pg_cnt = 0;
  334. unsigned int r_pg_cnt = 0;
  335. unsigned int dtbo_pg_cnt = 0;
  336. unsigned int dt_pg_cnt = 0;
  337. if (g_is_64bit_kernel)
  338. g_kmem_off = (unsigned int)target_get_scratch_address();
  339. else
  340. g_kmem_off = boot_hdr->kernel_addr;
  341. k_pg_cnt = (boot_hdr->kernel_sz + (pg_sz - 1)) / pg_sz;
  342. r_pg_cnt = (boot_hdr->ramdisk_sz + (pg_sz - 1)) / pg_sz;
  343. if (boot_hdr->header_version >= BOOT_HEADER_VERSION_ONE)
  344. dtbo_pg_cnt = (boot_hdr->recovery_dtbo_size + (pg_sz - 1)) / pg_sz;
  345. if (boot_hdr->header_version >= BOOT_HEADER_VERSION_TWO)
  346. dt_pg_cnt = (boot_hdr->dtb_size + (pg_sz - 1)) / pg_sz;
  347. dprintf(INFO, " > page count of kernel image = %d\n", k_pg_cnt);
  348. g_rmem_off = g_kmem_off + k_pg_cnt * pg_sz;
  349. dprintf(INFO, " > kernel mem offset = 0x%x\n", g_kmem_off);
  350. dprintf(INFO, " > rootfs mem offset = 0x%x\n", g_rmem_off);
  351. //***************
  352. //* specify boot image size
  353. //*
  354. g_bimg_sz = (k_pg_cnt + r_pg_cnt + dtbo_pg_cnt + dt_pg_cnt + 1) * pg_sz;
  355. dprintf(INFO, " > boot image size = 0x%x\n", g_bimg_sz);
  356. ret = verified_boot_flow("boot", "/boot");
  357. if (ret) {
  358. len = -1;
  359. return len;
  360. }
  361. }
  362. return len;
  363. }
  364. /**********************************************************
  365. * Routine: mboot_android_check_recoveryimg_hdr
  366. *
  367. * Description: this function is called to
  368. * (1) 'read' the header of boot image from nand flash
  369. * (2) 'parse' the header of boot image to obtain
  370. * - (a) kernel image size
  371. * - (b) rootfs image size
  372. * - (c) rootfs offset
  373. *
  374. * Notice : this function must be read first when doing nand / msdc boot
  375. *
  376. **********************************************************/
  377. static int mboot_android_check_recoveryimg_hdr(char *part_name,
  378. struct bootimg_hdr *boot_hdr)
  379. {
  380. int ret = 0;
  381. long len;
  382. //**********************************
  383. // TODO : fix pg_sz assignment
  384. //**********************************
  385. unsigned int pg_sz = 2 * 1024;
  386. //***************
  387. //* read partition header
  388. //*
  389. len = partition_read(part_name, 0, (uchar *) boot_hdr, sizeof(struct bootimg_hdr));
  390. if (len < 0) {
  391. dprintf(CRITICAL, "[%s] %s Recovery image header read error. LINE: %d\n",
  392. MODULE_NAME, part_name, __LINE__);
  393. return -1;
  394. }
  395. dprintf(CRITICAL,
  396. "\n============================================================\n");
  397. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Magic : 0x%08X\n",
  398. MODULE_NAME, boot_hdr->magic);
  399. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - OS Version : 0x%08X\n",
  400. MODULE_NAME, boot_hdr->os_version);
  401. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Kernel Size : 0x%08X\n",
  402. MODULE_NAME, boot_hdr->kernel_sz);
  403. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Kernel Address : 0x%08X\n",
  404. MODULE_NAME, boot_hdr->kernel_addr);
  405. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Rootfs Size : 0x%08X\n",
  406. MODULE_NAME, boot_hdr->ramdisk_sz);
  407. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Rootfs Address : 0x%08X\n",
  408. MODULE_NAME, boot_hdr->ramdisk_addr);
  409. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Tags Address : 0x%08X\n",
  410. MODULE_NAME, boot_hdr->tags_addr);
  411. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Page Size : 0x%08X\n",
  412. MODULE_NAME, boot_hdr->page_sz);
  413. dprintf(CRITICAL, "[%s] Android Recovery IMG Hdr - Command Line : %s\n",
  414. MODULE_NAME, boot_hdr->cmdline);
  415. dprintf(CRITICAL,
  416. "============================================================\n");
  417. //***************
  418. //* check partition magic
  419. //*
  420. if (strncmp((char const *)boot_hdr->magic, BOOTIMG_MAGIC, BOOTIMG_MAGIC_SZ) != 0) {
  421. dprintf(CRITICAL, "[%s] Recovery image header magic error\n", MODULE_NAME);
  422. return -1;
  423. }
  424. pg_sz = boot_hdr->page_sz;
  425. //***************
  426. //* follow bootimg.h to calculate the location of rootfs
  427. //*
  428. if (len != -1) {
  429. unsigned int k_pg_cnt = 0;
  430. unsigned int r_pg_cnt = 0;
  431. unsigned int dtbo_pg_cnt = 0;
  432. unsigned int dt_pg_cnt = 0;
  433. if (g_is_64bit_kernel)
  434. g_kmem_off = (unsigned int)target_get_scratch_address();
  435. else
  436. g_kmem_off = boot_hdr->kernel_addr;
  437. k_pg_cnt = (boot_hdr->kernel_sz + (pg_sz - 1)) / pg_sz;
  438. r_pg_cnt = (boot_hdr->ramdisk_sz + (pg_sz - 1)) / pg_sz;
  439. if (boot_hdr->header_version >= BOOT_HEADER_VERSION_ONE)
  440. dtbo_pg_cnt = (boot_hdr->recovery_dtbo_size + (pg_sz - 1)) / pg_sz;
  441. if (boot_hdr->header_version >= BOOT_HEADER_VERSION_TWO)
  442. dt_pg_cnt = (boot_hdr->dtb_size+ (pg_sz - 1)) / pg_sz;
  443. dprintf(INFO, " > page count of kernel image = %d\n", k_pg_cnt);
  444. g_rmem_off = g_kmem_off + k_pg_cnt * pg_sz;
  445. dprintf(INFO, " > kernel mem offset = 0x%x\n", g_kmem_off);
  446. dprintf(INFO, " > rootfs mem offset = 0x%x\n", g_rmem_off);
  447. //***************
  448. //* specify boot image size
  449. //*
  450. //g_rcimg_sz = part->start_sect * BLK_SIZE;
  451. g_rcimg_sz = (k_pg_cnt + r_pg_cnt + dtbo_pg_cnt + dt_pg_cnt + 1) * pg_sz;
  452. dprintf(INFO, " > Recovery image size = 0x%x\n", g_rcimg_sz);
  453. ret = verified_boot_flow("recovery", "/recovery");
  454. if (ret) {
  455. len = -1;
  456. return len;
  457. }
  458. }
  459. return len;
  460. }
  461. /**********************************************************
  462. * Routine: mboot_android_load_bootimg_hdr
  463. *
  464. * Description: this is the entry function to handle boot image header
  465. *
  466. **********************************************************/
  467. int mboot_android_load_bootimg_hdr(char *part_name, unsigned long addr)
  468. {
  469. long len;
  470. struct bootimg_hdr *boot_hdr;
  471. boot_hdr = (struct bootimg_hdr *)malloc(sizeof(struct bootimg_hdr));
  472. if (!boot_hdr) {
  473. dprintf(CRITICAL, "mboot_android_load_bootimg_hdr, boot_hdr = NULL\n");
  474. return -ENOMEM;
  475. }
  476. g_boot_hdr = boot_hdr;
  477. len = mboot_android_check_bootimg_hdr(part_name, boot_hdr);
  478. platform_parse_bootopt(boot_hdr->cmdline);
  479. return len;
  480. }
  481. /**********************************************************
  482. * Routine: mboot_android_load_recoveryimg_hdr
  483. *
  484. * Description: this is the entry function to handle Recovery image header
  485. *
  486. **********************************************************/
  487. int mboot_android_load_recoveryimg_hdr(char *part_name, unsigned long addr)
  488. {
  489. long len;
  490. struct bootimg_hdr *boot_hdr;
  491. boot_hdr = (struct bootimg_hdr *)malloc(sizeof(struct bootimg_hdr));
  492. if (!boot_hdr) {
  493. dprintf(CRITICAL, "mboot_android_load_bootimg_hdr, boot_hdr = NULL\n");
  494. return -ENOMEM;
  495. }
  496. g_boot_hdr = boot_hdr;
  497. len = mboot_android_check_recoveryimg_hdr(part_name, boot_hdr);
  498. return len;
  499. }
  500. /**********************************************************
  501. * Routine: mboot_android_load_bootimg
  502. *
  503. * Description: main function to load Android Boot Image
  504. *
  505. **********************************************************/
  506. int mboot_android_load_bootimg(char *part_name, unsigned long addr)
  507. {
  508. long len;
  509. unsigned long long start_addr;
  510. //***************
  511. //* not to include unused header
  512. //*
  513. start_addr = partition_get_offset_by_name(part_name) + g_boot_hdr->page_sz;
  514. /*
  515. * check mkimg header
  516. */
  517. dprintf(INFO, "check mkimg header\n");
  518. len = partition_read(part_name, g_boot_hdr->page_sz, (uchar *)addr,
  519. MKIMG_HEADER_SZ);
  520. if (len < 0) {
  521. dprintf(CRITICAL, "[%s] %s partition read error. LINE: %d\n", MODULE_NAME,
  522. part_name, __LINE__);
  523. return -EIO;
  524. }
  525. // check kernel header
  526. g_kimg_sz = mboot_android_check_img_info(PART_KERNEL, (part_hdr_t *)addr);
  527. if (g_kimg_sz == -1)
  528. dprintf(INFO, "no mkimg header in kernel image\n");
  529. else {
  530. dprintf(INFO, "mkimg header exist in kernel image\n");
  531. addr = addr - MKIMG_HEADER_SZ;
  532. g_rmem_off = g_rmem_off - MKIMG_HEADER_SZ;
  533. }
  534. //***************
  535. //* read image data
  536. //*
  537. dprintf(INFO, "\nread the data of %s (size = 0x%x)\n", part_name, g_bimg_sz);
  538. dprintf(INFO, " > from - 0x%016llx (skip boot img hdr)\n", start_addr);
  539. dprintf(INFO, " > to - 0x%x (starts with kernel img hdr)\n",
  540. (unsigned int)addr);
  541. len = partition_read(part_name, g_boot_hdr->page_sz, (uchar *)addr,
  542. (size_t)g_bimg_sz);
  543. // check ramdisk/rootfs header
  544. g_rimg_sz = mboot_android_check_img_info(PART_ROOTFS, (part_hdr_t *)g_rmem_off);
  545. if (g_rimg_sz == -1) {
  546. dprintf(INFO, "no mkimg header in ramdisk image\n");
  547. g_rimg_sz = g_boot_hdr->ramdisk_sz;
  548. } else {
  549. dprintf(INFO, "mkimg header exist in ramdisk image\n");
  550. g_rmem_off = g_rmem_off + MKIMG_HEADER_SZ;
  551. }
  552. if (len < 0)
  553. len = -EIO;
  554. return len;
  555. }
  556. /**********************************************************
  557. * Routine: mboot_android_load_recoveryimg
  558. *
  559. * Description: main function to load Android Recovery Image
  560. *
  561. **********************************************************/
  562. int mboot_android_load_recoveryimg(char *part_name, unsigned long addr)
  563. {
  564. long len;
  565. unsigned long long start_addr;
  566. //***************
  567. //* not to include unused header
  568. //*
  569. start_addr = partition_get_offset_by_name(part_name) + g_boot_hdr->page_sz;
  570. /*
  571. * check mkimg header
  572. */
  573. dprintf(INFO, "check mkimg header\n");
  574. len = partition_read(part_name, g_boot_hdr->page_sz, (uchar *)addr,
  575. MKIMG_HEADER_SZ);
  576. if (len < 0) {
  577. dprintf(CRITICAL, "[%s] %s partition read error. LINE: %d\n", MODULE_NAME,
  578. part_name, __LINE__);
  579. return -EIO;
  580. }
  581. // check kernel header
  582. g_kimg_sz = mboot_android_check_img_info(PART_KERNEL, (part_hdr_t *)addr);
  583. if (g_kimg_sz == -1)
  584. dprintf(INFO, "no mkimg header in kernel image\n");
  585. else {
  586. dprintf(INFO, "mkimg header exist in kernel image\n");
  587. addr = addr - MKIMG_HEADER_SZ;
  588. g_rmem_off = g_rmem_off - MKIMG_HEADER_SZ;
  589. }
  590. //***************
  591. //* read image data
  592. //*
  593. dprintf(INFO, "\nread the data of %s (size = 0x%x)\n", part_name, g_rcimg_sz);
  594. dprintf(INFO, " > from - 0x%016llx (skip recovery img hdr)\n", start_addr);
  595. dprintf(INFO, " > to - 0x%x (starts with kernel img hdr)\n",
  596. (unsigned int)addr);
  597. len = partition_read(part_name, g_boot_hdr->page_sz, (uchar *)addr,
  598. (size_t)g_rcimg_sz);
  599. // check ramdisk/rootfs header
  600. g_rimg_sz = mboot_android_check_img_info("recovery", (part_hdr_t *)g_rmem_off);
  601. if (g_rimg_sz == -1) {
  602. dprintf(INFO, "no mkimg header in recovery image\n");
  603. g_rimg_sz = g_boot_hdr->ramdisk_sz;
  604. } else {
  605. dprintf(INFO, "mkimg header exist in recovery image\n");
  606. g_rmem_off = g_rmem_off + MKIMG_HEADER_SZ;
  607. }
  608. if (len < 0)
  609. len = -EIO;
  610. return len;
  611. }
  612. /**********************************************************
  613. * Routine: mboot_recovery_load_raw_part
  614. *
  615. * Description: load raw data for recovery mode support
  616. *
  617. **********************************************************/
  618. int mboot_recovery_load_raw_part(char *part_name, unsigned long *addr,
  619. unsigned int size)
  620. {
  621. long len;
  622. unsigned long begin;
  623. begin = get_timer(0);
  624. #ifdef NON_ZERO_OFFSET_PROINFO_FORMAT
  625. if (strcmp(part_name, "proinfo") == 0)
  626. len = partition_read(part_name, PARTITION_SIZE, (uchar*)addr, (size_t)size);
  627. else
  628. #endif // NON_ZERO_OFFSET_PROINFO_FORMAT
  629. len = partition_read(part_name, 0, (uchar *)addr, (size_t)size);
  630. if (len < 0) {
  631. len = -EIO;
  632. goto exit;
  633. }
  634. dprintf(CRITICAL, "[%s] Load '%s' partition to 0x%08lX (%d bytes in %ld ms)\n",
  635. MODULE_NAME, part_name, (unsigned long)addr, size, get_timer(begin));
  636. exit:
  637. return len;
  638. }
  639. /**********************************************************
  640. * Routine: mboot_recovery_load_raw_part_offset
  641. *
  642. * Description: load partition raw data with offset
  643. *
  644. * offset and size must page alignemnt
  645. **********************************************************/
  646. int mboot_recovery_load_raw_part_offset(char *part_name, unsigned long *addr,
  647. unsigned long offset, unsigned int size)
  648. {
  649. long len;
  650. unsigned long begin;
  651. int blksz = storage_get_blksz();
  652. begin = get_timer(0);
  653. #ifdef NON_ZERO_OFFSET_PROINFO_FORMAT
  654. if (strcmp(part_name, "proinfo") == 0)
  655. len = partition_read(part_name, PARTITION_SIZE, (uchar*)addr, (size_t)size);
  656. else
  657. #endif // NON_ZERO_OFFSET_PROINFO_FORMAT
  658. len = partition_read(part_name, ROUNDUP(offset, blksz), (uchar *)addr, ROUNDUP(size, blksz));
  659. if (len < 0) {
  660. len = -EIO;
  661. goto exit;
  662. }
  663. dprintf(INFO, "[%s] Load '%s' partition to 0x%08lX (%d bytes in %ld ms)\n",
  664. MODULE_NAME, part_name, (unsigned long)addr, size, get_timer(begin));
  665. exit:
  666. return len;
  667. }
  668. /**********************************************************
  669. * Routine: mboot_recovery_load_misc
  670. *
  671. * Description: load recovery command
  672. *
  673. **********************************************************/
  674. int mboot_recovery_load_misc(unsigned long *misc_addr, unsigned int size)
  675. {
  676. int ret;
  677. dprintf(INFO, "[mboot_recovery_load_misc]: size is %u\n", size);
  678. dprintf(INFO, "[mboot_recovery_load_misc]: misc_addr is 0x%x\n",
  679. (unsigned int)misc_addr);
  680. ret = mboot_recovery_load_raw_part("para", misc_addr, size);
  681. if (ret < 0)
  682. return ret;
  683. return ret;
  684. }
  685. /**********************************************************
  686. * Routine: mboot_get_dtbo_img_size
  687. *
  688. * Description: Get img size from dtbo header
  689. The size include both image and header and the size is align to 16 bytes.
  690. *
  691. **********************************************************/
  692. unsigned int mboot_get_dtbo_img_size(char *part_name, unsigned int *size)
  693. {
  694. unsigned int ret = 0 ;
  695. long len = 0;
  696. struct dt_table_header dtboimg_hdr;
  697. if (part_name == NULL)
  698. return -ENOENT;
  699. if (size == NULL)
  700. return -ENOENT;
  701. *size = 0;
  702. len = partition_read(part_name, (off_t)0, (uchar *)&dtboimg_hdr,
  703. sizeof(struct dt_table_header));
  704. if (len < 0) {
  705. dprintf(CRITICAL, "[%s] partition %s not found, LINE: %d\n", MODULE_NAME,
  706. part_name, __LINE__);
  707. return -ENOENT;
  708. }
  709. *size = BigtoLittle32(dtboimg_hdr.total_size);
  710. dprintf(CRITICAL,
  711. "\n============================================================\n");
  712. dprintf(CRITICAL, "[%s] Partition Name\t\t\t: %s\n", MODULE_NAME, part_name);
  713. dprintf(CRITICAL, "[%s] Header Magic\t\t\t: %x\n", MODULE_NAME, dtboimg_hdr.magic);
  714. dprintf(CRITICAL, "[%s] IMG size\t\t\t\t: %x\n", MODULE_NAME, *size);
  715. dprintf(CRITICAL,
  716. "============================================================\n");
  717. *size = ROUNDUP((*size), DTBO_IMG_ALIGN_SZ);
  718. dprintf(CRITICAL, "[%s] IMG align size\t\t\t: %x\n", MODULE_NAME, *size);
  719. return ret;
  720. }
  721. /**********************************************************
  722. * Routine: mboot_get_inhouse_img_size
  723. *
  724. * Description: Get img size from mkimage header (LK,Logo)
  725. The size include both image and header and the size is align to 4k.
  726. *
  727. **********************************************************/
  728. unsigned int mboot_get_inhouse_img_size(char *part_name, unsigned int *size)
  729. {
  730. int ret = 0;
  731. long len = 0;
  732. part_hdr_t mkimage_hdr;
  733. unsigned page_sz = 0x1000;
  734. *size = 0;
  735. dprintf(CRITICAL, "Get inhouse img size from mkimage header\n");
  736. /*Read mkimage header*/
  737. len = partition_read(part_name, (off_t)0, (uchar *)&mkimage_hdr,
  738. (size_t)sizeof(part_hdr_t));
  739. if (len < 0) {
  740. dprintf(CRITICAL, "[%s] %s partition read error. LINE: %d\n", MODULE_NAME,
  741. part_name, __LINE__);
  742. return -EIO;
  743. }
  744. dprintf(CRITICAL,
  745. "\n============================================================\n");
  746. dprintf(CRITICAL, "[%s] INHOUSE Partition Name : %s\n", MODULE_NAME,
  747. part_name);
  748. dprintf(CRITICAL, "[%s] INHOUSE IMG HDR - Magic : %x\n", MODULE_NAME,
  749. mkimage_hdr.info.magic);
  750. dprintf(CRITICAL, "[%s] INHOUSE IMG size : %x\n",
  751. MODULE_NAME, mkimage_hdr.info.dsize);
  752. dprintf(CRITICAL, "[%s] INHOUSE IMG HDR size : %x\n",
  753. MODULE_NAME, sizeof(part_hdr_t));
  754. dprintf(CRITICAL,
  755. "============================================================\n");
  756. *size = (((mkimage_hdr.info.dsize + sizeof(part_hdr_t) + page_sz - 1) /
  757. page_sz) * page_sz);
  758. dprintf(CRITICAL, "[%s] INHOUSE IMG size : %x\n", MODULE_NAME, *size);
  759. return ret;
  760. }
  761. unsigned int mboot_get_bootimg_size(char *part_name, unsigned int *size)
  762. {
  763. int ret = 0;
  764. long len = 0;
  765. struct bootimg_hdr boot_hdr;
  766. /* use starting 16 bytes to get boot sig size */
  767. /* actual boot signature size is much bigger */
  768. #define BOOT_SIG_HDR_SZ 16
  769. unsigned char boot_sig_hdr[BOOT_SIG_HDR_SZ] = {0};
  770. unsigned boot_sig_size = 0;
  771. unsigned page_sz =
  772. 0x800; /* used to cache page size in boot image hdr, default 2KB */
  773. *size = 0;
  774. len = partition_read(part_name, (off_t)0, (uchar *)&boot_hdr,
  775. sizeof(struct bootimg_hdr));
  776. if (len < 0) {
  777. dprintf(CRITICAL, "[%s] %s boot image header read error. LINE: %d\n",
  778. MODULE_NAME, part_name, __LINE__);
  779. return -1;
  780. }
  781. boot_hdr.magic[7] = '\0';
  782. dprintf(CRITICAL,
  783. "\n============================================================\n");
  784. dprintf(CRITICAL, "[%s] Android Partition Name : %s\n", MODULE_NAME,
  785. part_name);
  786. dprintf(CRITICAL, "[%s] Android IMG Hdr - Magic : %s\n", MODULE_NAME,
  787. boot_hdr.magic);
  788. dprintf(CRITICAL, "[%s] Android IMG Hdr - Kernel Size : 0x%08X\n",
  789. MODULE_NAME, boot_hdr.kernel_sz);
  790. dprintf(CRITICAL, "[%s] Android IMG Hdr - Kernel Address : 0x%08X\n",
  791. MODULE_NAME, boot_hdr.kernel_addr);
  792. dprintf(CRITICAL, "[%s] Android IMG Hdr - Rootfs Size : 0x%08X\n",
  793. MODULE_NAME, boot_hdr.ramdisk_sz);
  794. dprintf(CRITICAL, "[%s] Android IMG Hdr - Rootfs Address : 0x%08X\n",
  795. MODULE_NAME, boot_hdr.ramdisk_addr);
  796. dprintf(CRITICAL, "[%s] Android IMG Hdr - Tags Address : 0x%08X\n",
  797. MODULE_NAME, boot_hdr.tags_addr);
  798. dprintf(CRITICAL, "[%s] Android IMG Hdr - Page Size : 0x%08X\n",
  799. MODULE_NAME, boot_hdr.page_sz);
  800. dprintf(CRITICAL, "[%s] Android IMG Hdr - Command Line : %s\n", MODULE_NAME,
  801. boot_hdr.cmdline);
  802. dprintf(CRITICAL,
  803. "============================================================\n");
  804. page_sz = boot_hdr.page_sz;
  805. *size += page_sz; /* boot header size is 1 page*/
  806. *size += (((boot_hdr.kernel_sz + page_sz - 1) / page_sz) * page_sz);
  807. *size += (((boot_hdr.ramdisk_sz + page_sz - 1) / page_sz) * page_sz);
  808. *size += (((boot_hdr.second_sz + page_sz - 1) / page_sz) * page_sz);
  809. if (boot_hdr.header_version >= BOOT_HEADER_VERSION_ONE)
  810. *size += (((boot_hdr.recovery_dtbo_size + page_sz - 1) / page_sz) * page_sz);
  811. if (boot_hdr.header_version >= BOOT_HEADER_VERSION_TWO)
  812. *size += (((boot_hdr.dtb_size + page_sz - 1) / page_sz) * page_sz);
  813. /* try to get boot siganture size if it exists */
  814. len = partition_read(part_name, (off_t)(*size), (uchar *)&boot_sig_hdr,
  815. (size_t)BOOT_SIG_HDR_SZ);
  816. if (len < 0) {
  817. dprintf(CRITICAL, "[%s] %s boot sig header read error. LINE: %d\n", MODULE_NAME,
  818. part_name, __LINE__);
  819. return -1;
  820. }
  821. /* in case boot image is signed by boot signer */
  822. #define ASN_ID_SEQUENCE 0x30
  823. if (boot_sig_hdr[0] == ASN_ID_SEQUENCE) {
  824. /* boot signature exists */
  825. unsigned len = 0;
  826. unsigned len_size = 0;
  827. if (boot_sig_hdr[1] & 0x80) {
  828. /* multi-byte length field */
  829. unsigned int i = 0;
  830. len_size = 1 + (boot_sig_hdr[1] & 0x7f);
  831. for (i = 0; i < len_size - 1; i++)
  832. len = (len << 8) | boot_sig_hdr[2 + i];
  833. } else {
  834. /* single-byte length field */
  835. len_size = 1;
  836. len = boot_sig_hdr[1];
  837. }
  838. boot_sig_size = 1 + len_size + len;
  839. }
  840. *size += (((boot_sig_size + page_sz - 1) / page_sz) * page_sz);
  841. return ret;
  842. }
  843. unsigned int mboot_get_img_size(char *part_name, unsigned int *size)
  844. {
  845. int ret = 0;
  846. struct bootimg_hdr *boot_hdr = NULL;
  847. struct dt_table_header *dtboimg_hdr = NULL;
  848. uint8_t hdr[sizeof(struct bootimg_hdr)] = {0};
  849. *size = 0;
  850. long len = partition_read(part_name, (off_t)0, hdr,
  851. sizeof(struct bootimg_hdr));
  852. if (len < 0) {
  853. dprintf(CRITICAL, "[%s] Error reading %s! LINE: %d\n", MODULE_NAME, part_name,
  854. __LINE__);
  855. return -1;
  856. }
  857. boot_hdr = (struct bootimg_hdr *)hdr;
  858. dtboimg_hdr = (struct dt_table_header *)hdr;
  859. if (!memcmp(boot_hdr->magic, BOOTIMG_MAGIC, BOOTIMG_MAGIC_SZ))
  860. return mboot_get_bootimg_size(part_name, size);
  861. else if (dtboimg_hdr->magic == BigtoLittle32(DT_TABLE_MAGIC))
  862. return mboot_get_dtbo_img_size(part_name, size);
  863. else
  864. return mboot_get_inhouse_img_size(part_name, size);
  865. return ret;
  866. }