2020.0.14-Android开机启动流程完全详细分析(1)

文章目录

  • uboot 启动
    • 1.bsp/bootloader/u-boot15/arch/arm/cpu/armv8/start.S:
    • 2.main函数
    • 3.bsp/bootloader/u-boot15/arch/arm/lib/board.c
    • 4.main_loop
  • kernel 启动
  • 启动挂载分区
  • 挂载分区过程

Android 11(Android Q)分区挂载过程分析

uboot 启动

1.bsp/bootloader/u-boot15/arch/arm/cpu/armv8/start.S:

进行CPU,中断,寄存器,时钟等的初始化,然后进行lowlevel_init,最后跳转到_main函数入口,

2.main函数

定义在bsp/bootloader/u-boot15/arch/arm/lib/crt0.S ,在main函数中,初始化CPU,SPL,以及各个内存段初始化,bl board_init_f,调用board_init_f函数。

3.bsp/bootloader/u-boot15/arch/arm/lib/board.c

对cache,board,cpu_clk,serial,log,mem,flash,env,malloc mem,nand,mmc, BOOT_DEVICE_UFS,BOOT_DEVICE_EMMC,board_mmc_initialize,scsi_init,dataflash,arm_pci_init,stdio_initapi_init,console_init_r,misc_init_r,interrupt_init,board_late_init。最后跳转到main_loop。

787  	for (;;) {
788  		main_loop();
789  	}

4.main_loop

/**/
modem_init();
/**/
cli_init();
/**/
run_preboot_environment_command();
/**/
s = bootdelay_process();
/**/
cli_secure_boot_cmd(s);
/**/
autoboot_command(s);
/**/
cli_loop();
56  void main_loop(void)
57  {
58  	const char *s;
59  
60  	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
61  
62  #ifndef CONFIG_SYS_GENERIC_BOARD
63  	debug("Warning: Your board does not use generic board. Please read\n");
64  	debug("doc/README.generic-board and take action. Boards not\n");
65  	debug("upgraded by the late 2014 may break or be removed.\n");
66  #endif
67  
68  	modem_init();
69  #ifdef CONFIG_VERSION_VARIABLE
70  	setenv("ver", version_string);  /* set version variable */
71  #endif /* CONFIG_VERSION_VARIABLE */
72  
73  	cli_init();
74  
75  	run_preboot_environment_command();
76  
77  #if defined(CONFIG_UPDATE_TFTP)
78  	update_tftp(0UL);
79  #endif /* CONFIG_UPDATE_TFTP */
80  //bootm console 超时以后自动启动getenv("bootm")的值,执行启动。
81  	s = bootdelay_process();
82  	if (cli_process_fdt(&s))
83  		cli_secure_boot_cmd(s);
84  //在进行自动启动时,获取menucmd的环境变量的值,然后执行该命令。
85  	autoboot_command(s);
86  //当uboot console 获取到了指令后,会之下下面的语句,循环获取console的指令,采用了hush shell 获取,解析,执行命令。
87  	cli_loop();
88  }
212  void cli_init(void)
213  {
214  #ifdef CONFIG_SYS_HUSH_PARSER
215  	u_boot_hush_start();
216  #endif
217  
218  #if defined(CONFIG_HUSH_INIT_VAR)
219  	hush_init_var();
220  #endif
221  }

初始化并配置hush

271  struct variables {
272  	char *name;
273  	char *value;
274  	int flg_export;
275  	int flg_read_only;
276  	struct variables *next;
277  };

3291  int u_boot_hush_start(void)
3292  {
3293  	if (top_vars == NULL) {
3294  		top_vars = malloc(sizeof(struct variables));
3295  		top_vars->name = "HUSH_VERSION";
3296  		top_vars->value = "0.01";
3297  		top_vars->next = NULL;
3298  		top_vars->flg_export = 0;
3299  		top_vars->flg_read_only = 1;
3300  #ifdef CONFIG_NEEDS_MANUAL_RELOC
3301  		u_boot_hush_reloc();
3302  #endif
3303  	}
3304  	return 0;
3305  }

423  #if defined(CONFIG_HUSH_INIT_VAR)
424  int hush_init_var(void)
425  {
426  	ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
427  	return 0;
428  }
429  #endif
304  const char *bootdelay_process(void)
305  {
306  	char *s;
307  	int bootdelay;
308  #ifdef CONFIG_BOOTCOUNT_LIMIT
309  	unsigned long bootcount = 0;
310  	unsigned long bootlimit = 0;
311  #endif /* CONFIG_BOOTCOUNT_LIMIT */
312  
313  #ifdef CONFIG_BOOTCOUNT_LIMIT
314  	bootcount = bootcount_load();
315  	bootcount++;
316  	bootcount_store(bootcount);
317  	setenv_ulong("bootcount", bootcount);
318  	bootlimit = getenv_ulong("bootlimit", 10, 0);
319  #endif /* CONFIG_BOOTCOUNT_LIMIT */
320  
321  	s = getenv("bootdelay");
322  	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
323  
324  #ifdef CONFIG_OF_CONTROL
325  	bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
326  			bootdelay);
327  #endif
328  
329  	debug("### main_loop entered: bootdelay=%d\n\n", bootdelay);
330  
331  #if defined(CONFIG_MENU_SHOW)
332  	bootdelay = menu_show(bootdelay);
333  #endif
334  	bootretry_init_cmd_timeout();
335  
336  #ifdef CONFIG_POST
337  	if (gd->flags & GD_FLG_POSTFAIL) {
338  		s = getenv("failbootcmd");
339  	} else
340  #endif /* CONFIG_POST */
341  #ifdef CONFIG_BOOTCOUNT_LIMIT
342  	if (bootlimit && (bootcount > bootlimit)) {
343  		printf("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
344  		       (unsigned)bootlimit);
345  		s = getenv("altbootcmd");
346  	} else
347  #endif /* CONFIG_BOOTCOUNT_LIMIT */
348  		s = getenv("bootcmd");
349  
350  	process_fdt_options(gd->fdt_blob);
351  	stored_bootdelay = bootdelay;
352  
353  	return s;
354  }

循环执行cli 处理uboot console 指令

201  void cli_loop(void)
202  {
203  #ifdef CONFIG_SYS_HUSH_PARSER
204  	parse_file_outer();
205  	/* This point is never reached */
206  	for (;;);
207  #else
208  	cli_simple_loop();
209  #endif /*CONFIG_SYS_HUSH_PARSER*/
210  }
211  
212  void cli_init(void)
213  {
214  #ifdef CONFIG_SYS_HUSH_PARSER
215  	u_boot_hush_start();
216  #endif
217  
218  #if defined(CONFIG_HUSH_INIT_VAR)
219  	hush_init_var();
220  #endif
221  }

simple 解析函数

259  void cli_simple_loop(void)
260  {
261  	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
262  
263  	int len;
264  	int flag;
265  	int rc = 1;
266  
267  	for (;;) {
268  		if (rc >= 0) {
269  			/* Saw enough of a valid command to
270  			 * restart the timeout.
271  			 */
272  			bootretry_reset_cmd_timeout();
273  		}
274  		len = cli_readline(CONFIG_SYS_PROMPT);
275  
276  		flag = 0;	/* assume no special flags for now */
277  		if (len > 0)
278  			strcpy(lastcommand, console_buffer);
279  		else if (len == 0)
280  			flag |= CMD_FLAG_REPEAT;
281  #ifdef CONFIG_BOOT_RETRY_TIME
282  		else if (len == -2) {
283  			/* -2 means timed out, retry autoboot
284  			 */
285  			puts("\nTimed out waiting for command\n");
286  # ifdef CONFIG_RESET_TO_RETRY
287  			/* Reinit board to run initialization code again */
288  			do_reset(NULL, 0, 0, NULL);
289  # else
290  			return;		/* retry autoboot */
291  # endif
292  		}
293  #endif
294  
295  		if (len == -1)
296  			puts("\n");
297  		else
298  			rc = run_command_repeatable(lastcommand, flag);
299  
300  		if (rc <= 0) {
301  			/* invalid command or not repeatable, forget it */
302  			lastcommand[0] = 0;
303  		}
304  	}
305  }

hush 解析函数

3260  #ifndef __U_BOOT__
3261  static int parse_file_outer(FILE *f)//no excuese
3262  #else
3263  int parse_file_outer(void)
3264  #endif
3265  {
3266  	int rcode;
3267  	struct in_str input;
3268  #ifndef __U_BOOT__
3269  	setup_file_in_str(&input, f);//no excuese
3270  #else
3271  	setup_file_in_str(&input);
3272  #endif
3273  	rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
3274  	return rcode;
3275  }

326  /* I can almost use ordinary FILE *.  Is open_memstream() universally
327   * available?  Where is it documented? */
328  struct in_str {
329  	const char *p;
330  #ifndef __U_BOOT__
331  	char peek_buf[2];
332  #endif
333  	int __promptme;
334  	int promptmode;
335  #ifndef __U_BOOT__
336  	FILE *file;
337  #endif
338  	int (*get) (struct in_str *);
339  	int (*peek) (struct in_str *);
340  };
      //获取输入指令然后结构化
1130  #ifndef __U_BOOT__
1131  static void setup_file_in_str(struct in_str *i, FILE *f)
1132  #else
1133  static void setup_file_in_str(struct in_str *i)
1134  #endif
1135  {
1136  	i->peek = file_peek;
1137  	i->get = file_get;
1138  	i->__promptme=1;
1139  	i->promptmode=1;
1140  #ifndef __U_BOOT__
1141  	i->file = f;
1142  #endif
1143  	i->p = NULL;
1144  }

/* most recursion does not come through here, the exeception is
3157   * from builtin_source() */
3158  static int parse_stream_outer(struct in_str *inp, int flag)
3159  {
3160  
3161  	struct p_context ctx;
3162  	o_string temp=NULL_O_STRING;
3163  	int rcode;
3164  #ifdef __U_BOOT__
3165  	int code = 1;
3166  #endif
3167  	do {
3168  		ctx.type = flag;
3169  		initialize_context(&ctx);
3170  		update_ifs_map();
3171  		if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";$&|", 0);
3172  		inp->promptmode=1;
3173  		rcode = parse_stream(&temp, &ctx, inp,
3174  				     flag & FLAG_CONT_ON_NEWLINE ? -1 : '\n');
3175  #ifdef __U_BOOT__
3176  		if (rcode == 1) flag_repeat = 0;
3177  #endif
3178  		if (rcode != 1 && ctx.old_flag != 0) {
3179  			syntax();
3180  #ifdef __U_BOOT__
3181  			flag_repeat = 0;
3182  #endif
3183  		}
3184  		if (rcode != 1 && ctx.old_flag == 0) {
3185  			done_word(&temp, &ctx);
3186  			done_pipe(&ctx,PIPE_SEQ);
3187  #ifndef __U_BOOT__
3188  			run_list(ctx.list_head);
3189  #else
3190  			code = run_list(ctx.list_head);
3191  			if (code == -2) {	/* exit */
3192  				b_free(&temp);
3193  				code = 0;
3194  				/* XXX hackish way to not allow exit from main loop */
3195  				if (inp->peek == file_peek) {
3196  					printf("exit not allowed from main input shell.\n");
3197  					continue;
3198  				}
3199  				break;
3200  			}
3201  			if (code == -1)
3202  			    flag_repeat = 0;
3203  #endif
3204  		} else {
3205  			if (ctx.old_flag != 0) {
3206  				free(ctx.stack);
3207  				b_reset(&temp);
3208  			}
3209  #ifdef __U_BOOT__
3210  			if (inp->__promptme == 0) printf("\n");
3211  			inp->__promptme = 1;
3212  #endif
3213  			temp.nonnull = 0;
3214  			temp.quote = 0;
3215  			inp->p = NULL;
3216  			free_pipe_list(ctx.list_head,0);
3217  		}
3218  		b_free(&temp);
3219  	/* loop on syntax errors, return on EOF */
3220  	} while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP) &&
3221  		(inp->peek != static_peek || b_peek(inp)));
3222  #ifndef __U_BOOT__
3223  	return 0;
3224  #else
3225  	return (code != 0) ? 1 : 0;
3226  #endif /* __U_BOOT__ */
3227  }

uboot引导启动:

     //填入uboot 指令
400  U_BOOT_CMD(
401  		  cboot, CONFIG_SYS_MAXARGS, 1, do_cboot,
402  		  "choose boot mode",
403  		  "mode: \nrecovery, fastboot, dloader, charge, normal, vlx, caliberation.\n"
404  		  "cboot could enter a mode specified by the mode descriptor.\n"
405  		  "it also could enter a proper mode automatically depending on "
406  		  "the environment\n"
407  		);
408  

150  #define ll_entry_declare(_type, _name, _list)				\
151  	_type _u_boot_list_2_##_list##_2_##_name __aligned(4)		\
152  			__attribute__((unused,				\
153  			section(".u_boot_list_2_"#_list"_2_"#_name)))

148  #define CMD_FLAG_REPEAT		0x0001	/* repeat last command		*/
149  #define CMD_FLAG_BOOTD		0x0002	/* command is from bootd	*/
150  #define CMD_FLAG_ENV		0x0004	/* command is from the environment */

152  #ifdef CONFIG_AUTO_COMPLETE
153  # define _CMD_COMPLETE(x) x,
154  #else
155  # define _CMD_COMPLETE(x)
156  #endif
157  #ifdef CONFIG_SYS_LONGHELP
158  # define _CMD_HELP(x) x,
159  #else
160  # define _CMD_HELP(x)
161  #endif

163  #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
164  				_usage, _help, _comp)			\
165  		{ #_name, _maxargs, _rep, _cmd, _usage,			\
166  			_CMD_HELP(_help) _CMD_COMPLETE(_comp) }

172  #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
173  	ll_entry_declare(cmd_tbl_t, _name, cmd) =			\
174  		U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,	\
175  						_usage, _help, _comp);

177  #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)		\
178  	U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

###main_loop: bootcmd=“cboot”

 int do_cboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
323  {
324  	volatile int i;
325  	boot_mode_enum_type bootmode = CMD_UNDEFINED_MODE;
326  	CBOOT_MODE_ENTRY boot_mode_array[CMD_MAX_MODE] ={0};
327  
328  	if(argc > 2)
329  		return CMD_RET_USAGE;
330  #ifdef CONFIG_AUTOLOAD_MODE
331  	autoload_mode();
332  #endif
333  
334  #ifdef CONFIG_ANDROID_AB
335  	do_selcet_ab();
336  #endif
337  
338  #if defined CONFIG_AUTOBOOT
339  	if (reboot_mode_check() == CMD_AUTODLOADER_REBOOT)
340  	{
341  		autodloader_mode();
342  	}
343  	else    {
344  	#if defined CONFIG_X86
345  		write_sysdump_before_boot_extend();//if autoboot kernel is crash and reboot,the uboot go to sysdump in x86;
346  	#endif
347  		normal_mode();
348  	}
349  #endif
350  
351  #if defined CONFIG_ZEBU || defined CONFIG_FPGA
352  	normal_mode();
353  #endif
354  	boot_pwr_check();
355  	if (2 == argc) {
356  		/*argument has the highest priority to determine the boot mode*/
357  		bootmode = get_mode_from_arg(argv[1]);
358  	} else {
359  		for (i = 0;  i < CHECK_BOOTMODE_FUN_NUM; i++) {
360  			if (0 == s_boot_func_array[i]) {
361  				bootmode = CMD_POWER_DOWN_DEVICE;
362  				break;
363  			}
364  			bootmode = s_boot_func_array[i]();
365  			if (CMD_UNDEFINED_MODE == bootmode) {
366  
367  				continue;
368  			} else {
369  				debugf("get boot mode in boot func array[%d]\n",i);
370  				break;
371  			}
372  		}
373  	}
374  
375  	board_boot_mode_regist(boot_mode_array);
376  
377  	printf("enter boot mode %d\n", bootmode);
378  
379  	if ((bootmode > CMD_POWER_DOWN_DEVICE) &&(bootmode < CMD_MAX_MODE)&& (0 != boot_mode_array[bootmode])) {
380  		write_log();
381  
382  		boot_mode_array[bootmode]();
383  	} else {
384  #ifdef CONFIG_FPGA
385  		/*FPGA has no power button ,if hasn't detect any mode ,use normal mode*/
386  		debugf("FPGA use normal mode instead of power down.\n");
387  		normal_mode();
388  #else
389  		debugf("power down device\n");
390  		write_log();
391  		power_down_devices(0);
392  #endif
393  		while(1);
394  	}
395  
396  	  return 0;
397  }
398  
399  
400  U_BOOT_CMD(
401  		  cboot, CONFIG_SYS_MAXARGS, 1, do_cboot,
402  		  "choose boot mode",
403  		  "mode: \nrecovery, fastboot, dloader, charge, normal, vlx, caliberation.\n"
404  		  "cboot could enter a mode specified by the mode descriptor.\n"
405  		  "it also could enter a proper mode automatically depending on "
406  		  "the environment\n"
407  		);

//设置setenv("bootcmd", "cboot");
36  int do_role(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
37  {
38  #ifdef CONFIG_ZEBU
39  	boot_mode_t boot_role = BOOTLOADER_MODE_LOAD;
40  #else
41  	boot_mode_t boot_role = get_boot_role();
42  #endif
43  	switch(boot_role) {
44  		case BOOTLOADER_MODE_DOWNLOAD:
45  			setenv("bootdelay", "0");
46  			setenv("bootcmd", "download");
47  			debugf("Get chipram env mode %x,go download\n", boot_role);
48  			break;
49  		case BOOTLOADER_MODE_LOAD:
50  			setenv("bootcmd", "cboot");
51  			debugf("Get chipram env mode %x,go cboot\n", boot_role);
52  			break;
53  		default :
54  			printf("unkown uboot role ,nothing to do in preboot\n");
55  	}
56  
57  	return 0;
58  }
59  
60  
61  U_BOOT_CMD(
62  		  role, CONFIG_SYS_MAXARGS, 1, do_role,
63  		  "choose the role of spreadtrum uboot",
64  		  "two roles:dloader and cboot\n"
65  		);

定义启动函数:

110  CBOOT_FUNC s_boot_func_array[CHECK_BOOTMODE_FUN_NUM] = {
111  #ifdef CONFIG_SPRD_PLATFORM
112          //get_mode_from_bat_low,
113          write_sysdump_before_boot_extend,
114  	/* 1 get mode from file*/
115  	get_mode_from_file_extend,
116  	/* 2 get mode from watch dog */
117  	get_mode_from_watchdog,
118  	/* 3 get mode from alarm register */
119  	get_mode_from_alarm_register,
120  	/* 0 get mode from calibration detect */
121  	get_mode_from_calibration,
122  	/*4 get mode from charger */
123  	get_mode_from_charger,
124  	/*5 get mode from keypad*/
125  	get_mode_from_keypad,
126  	0
127  #else
128  	0
129  #endif
130  };

选择boot mode:

reboot_mode_check() 

bootmode = get_mode_from_arg(argv[1]);

for (i = 0;  i < CHECK_BOOTMODE_FUN_NUM; i++) {
360  			if (0 == s_boot_func_array[i]) {
361  				bootmode = CMD_POWER_DOWN_DEVICE;
362  				break;
363  			}
364  			bootmode = s_boot_func_array[i]();
365  			if (CMD_UNDEFINED_MODE == bootmode) {
366  
367  				continue;
368  			} else {
369  				debugf("get boot mode in boot func array[%d]\n",i);
370  				break;
371  			}
372  		}

注册boot 函数:

board_boot_mode_regist(boot_mode_array);

81  CBOOT_FUNC s_boot_func_array[CHECK_BOOTMODE_FUN_NUM] = {
82  #ifndef CONFIG_FPGA
83  	get_mode_from_bat_low,
84  	write_sysdump_before_boot_extend,
85  	/* 1 get mode from file*/
86  	get_mode_from_file_extend,
87  	/* 2 get mode from watch dog */
88  	get_mode_from_watchdog,
89  	/* 3 get mode from alarm register */
90  	get_mode_from_alarm_register,
91  	/* 0 get mode from calibration detect */
92  	get_mode_from_pctool,
93  	/*4 get mode from charger */
94  	get_mode_from_charger,
95  	/*5 get mode from keypad*/
96  	get_mode_from_keypad,
97  	0
98  #else
99  	0
100  #endif
101  };
102  
103  void board_boot_mode_regist(CBOOT_MODE_ENTRY *array)
104  {
105  	MODE_REGIST(CMD_NORMAL_MODE, normal_mode);
106  	MODE_REGIST(CMD_RECOVERY_MODE, recovery_mode);
107  	MODE_REGIST(CMD_FASTBOOT_MODE, fastboot_mode);
108  	MODE_REGIST(CMD_WATCHDOG_REBOOT, watchdog_mode);
109  	MODE_REGIST(CMD_AP_WATCHDOG_REBOOT, ap_watchdog_mode);
110  	MODE_REGIST(CMD_UNKNOW_REBOOT_MODE, unknow_reboot_mode);
111  	MODE_REGIST(CMD_PANIC_REBOOT, panic_reboot_mode);
112  	MODE_REGIST(CMD_AUTODLOADER_REBOOT, autodloader_mode);
113  	MODE_REGIST(CMD_SPECIAL_MODE, special_mode);
114  	MODE_REGIST(CMD_CHARGE_MODE, charge_mode);
115  	MODE_REGIST(CMD_ENGTEST_MODE,engtest_mode);
116  	MODE_REGIST(CMD_FACTORYTEST_MODE, factorytest_mode);
117  	MODE_REGIST(CMD_CALIBRATION_MODE, calibration_mode);
118  	MODE_REGIST(CMD_EXT_RSTN_REBOOT_MODE, normal_mode);
119  	MODE_REGIST(CMD_IQ_REBOOT_MODE, iq_mode);
120  	MODE_REGIST(CMD_ALARM_MODE, alarm_mode);
121  	MODE_REGIST(CMD_SPRDISK_MODE, sprdisk_mode);
122  	MODE_REGIST(CMD_AUTOTEST_MODE, autotest_mode);
123  	return;
124  }

启动前secureboot验证img:

153  void unknow_reboot_mode(void)
154  {
155  	debugf("unknow_reboot_mode\n");
156  	setenv("bootmode", "unknowreboot");
157  	vlx_nand_boot(BOOT_PART, BACKLIGHT_OFF, LCD_ON);
158  	return;
159  
160  }

232  void autodloader_mode(void)
233  {
234  	debugf("Enter autodloader mode\n");
235  
236  #ifdef CONFIG_ERASE_SPL_AUTO_DOWNLOAD
237  	if (0 != erase_spl_enter_download_mode()) {
238  		debugf("erase partition splloader and splloader_bak fail!\n");
239  		debugf("enter old autodloader_mode!\n");
240  	}
241  #endif
242  
243  #if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SPRD_SOC_SP9853I)
244  	tos_start_notify();
245  #endif
246  
247  #ifdef CONFIG_SECBOOT
248  	get_secboot_base_from_dt();
249  #endif
250  	/* remap iram */
251  	//autodlader_remap();
252  	/* main handler receive and jump */
253  	autodloader_mainhandler();
254  
255  	/*reach here means error happened*/
256  	return;
257  }

72  void normal_mode(void)
73  {
74  #ifndef CONFIG_ZEBU
75  	vibrator_hw_init();
76  
77  	set_vibrator(1);
78  	vlx_nand_boot(BOOT_PART, BACKLIGHT_ON, LCD_ON);
79  #else
80  	vlx_nand_boot_zebu(BOOT_PART, BACKLIGHT_ON, LCD_ON);
81  #endif
82  	return;
83  }

uboot 完成初始化和校验,加载img,启动kernel

void vlx_nand_boot(char *kernel_pname, int backlight_set, int lcd_enable)
1827  {
1828  	boot_img_hdr *hdr = (void *)raw_header;
1829  	char *mode_ptr = NULL;
1830  	uchar *partition = NULL;
1831  	int i = 0;
1832  	int j = 0;
1833  	int ret = 0;
1834  	uchar *dt_adr = DT_ADR;
1835  	uint32_t lcd_init_time;
1836  	uint32_t backlight_on_time;
1837  	uint32_t uboot_consume_time;
1838  
1839  #ifdef CONFIG_SOC_IWHALE2
1840  	aon_lpc_config();
1841  #endif
1842  	wakeup_source_enable();
1843  	ap_clk_doze_enable();
1844  
1845  #ifdef CONFIG_SPLASH_SCREEN
1846  	lcd_init_time = SCI_GetTickCount();
1847  	printf("lcd start init time:%dms\n", lcd_init_time);
1848  	if(lcd_enable) {
1849  		extern void lcd_enable(void);
1850  		debug("[LCD] Drawing the logo...\n");
1851  		drv_lcd_init();
1852  		lcd_splash(LOGO_PART);
1853  		lcd_enable();
1854  	}
1855  #ifdef CONFIG_SPRD_SOC_SP9853I
1856  	else {
1857  		/*if no lcd in cali mode, turn off the cam_eb bit*/
1858  		char  *boot_mode_type_str;
1859  
1860  		boot_mode_type_str = getenv("bootmode");
1861  		if(!strncmp(boot_mode_type_str, "cali", 4)) {
1862  			sci_glb_clr(REG_AON_APB_APB_EB1, BIT_AON_APB_AON_CAM_EB);
1863  		}
1864  
1865  	}
1866  #endif
1867  	set_backlight(backlight_set);
1868  	backlight_on_time = SCI_GetTickCount();
1869  	lcd_init_time= backlight_on_time - lcd_init_time;
1870  	uboot_consume_time = backlight_on_time - uboot_start_time;
1871  	printf("uboot consume time:%dms, lcd init consume:%dms, backlight on time:%dms \n", \
1872  		uboot_consume_time, lcd_init_time, backlight_on_time);
1873  
1874  #endif
1875  	set_vibrator(0);
1876  
1877  #if 0
1878  #ifdef CONFIG_SECBOOT
1879  	//init fastboot lock data
1880  	init_fblockflag();
1881  #endif
1882  #endif
1883  
1884  #if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SOC_IWHALE2) && (defined CONFIG_SECBOOT)
1885  	tos_status_check();
1886  #endif
1887  
1888  #if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SPRD_SOC_SP9853I)
1889      tos_start_notify();
1890  #endif
1891  
1892  #if defined(CONFIG_SECURE_BOOT)||defined(CONFIG_SECBOOT)
1893  	if (0 == memcmp(kernel_pname, RECOVERY_PART, strlen(RECOVERY_PART))) {
1894  #ifdef CONFIG_ANDROID_AB
1895  		partition = "boot";
1896  #else
1897  		partition = "recovery";
1898  #endif
1899  	} else {
1900  		partition = "boot";
1901  	}
1902  #if defined (CONFIG_SECURE_BOOT)
1903  	secure_verify_partition(dev, partition, KERNEL_ADR);
1904  #endif
1905  
1906  #if defined (CONFIG_SECBOOT)
1907  	/***secboot only 3 steps***/
1908  	/***secboot 1st step***/
1909  	secboot_init(partition);
1910  
1911  	/***secboot 2nd step***/
1912  	/*set v-boot binding data eg:lock status*/
1913  	loader_binding_data_set();
1914  	pass_pubkey_to_tos();
1915  
1916  	vboot_secure_process_flow(partition);
1917  #endif
1918  #endif
1919  
1920  		/*load required image which config in table */
1921  		i = 0;
1922  #ifdef CONFIG_ARM7_RAM_ACTIVE
1923  #ifdef CONFIG_SOC_IWHALE2
1924  		/*Just for iwhale2 bringup --from Sheng.Zhu advice*/
1925  		ag_tg_ldsp_hold();
1926  #endif
1927  #ifndef CONFIG_SPRD_SP_UART
1928  		pmic_arm7_RAM_active();
1929  #endif
1930  #endif
1931  
1932  
1933  	while (s_boot_image_table[i]) {
1934  		j = 0;
1935  		while (s_boot_image_table[i][j].partition) {
1936  			_boot_load_required_image(s_boot_image_table[i][j]);
1937  			j++;
1938  		}
1939  		i++;
1940  	}
1941  
1942  extern unsigned int g_charger_mode;
1943  #if defined(CONFIG_KERNEL_BOOT_CP)
1944  	if(g_charger_mode) {
1945          	boot_image_required_t pm_image = {"pm_sys", NULL, DFS_SIZE, DFS_ADDR};
1946  		_boot_load_required_image(pm_image);
1947  	}
1948  #endif
1949  
1950  #if !defined(CONFIG_KERNEL_BOOT_CP) && defined(CONFIG_MEM_LAYOUT_DECOUPLING)
1951  	extern boot_image_required_t *get_cp_load_table(void);
1952  	do {
1953  		boot_image_required_t *cp_load_table = NULL;
1954  		cp_load_table = get_cp_load_table();
1955  		printf("cp_load_table = 0x%p\n", cp_load_table);
1956  		if (NULL != cp_load_table) {
1957  			for(i = 0; cp_load_table[i].size > 0; i++) {
1958  				_boot_load_required_image(cp_load_table[i]);
1959  			}
1960  		}
1961  	} while(0);
1962  #endif
1963  
1964  #if defined (CONFIG_SECBOOT)
1965  		secboot_secure_process_flow(partition,0,0,(char *)gd->verify_base);
1966  		//things to do refer to verify ret
1967  		take_action_with_vbootret();
1968  
1969  		if(set_root_of_trust(root_of_trust_str, ROOT_OF_TRUST_MAXSIZE)) {
1970  			printf("set_root_of_trust failed.\n");
1971  		} else {
1972  			printf("set_root_of_trust succeeded.\n");
1973  		}
1974  #endif
1975  
1976  #ifdef OTA_BACKUP_MISC_RECOVERY
1977  	ret = memcmp(kernel_pname, RECOVERY_PART, strlen(RECOVERY_PART));
1978  	if ((ret != 0) || (boot_load_recovery_in_sd(hdr) != 0))
1979  		if (!_boot_load_kernel_ramdisk_image(kernel_pname, hdr, &dt_adr))
1980  			ret = -1;
1981  #else
1982  	/*loader kernel and ramdisk*/
1983  	if (!_boot_load_kernel_ramdisk_image(kernel_pname, hdr, &dt_adr))
1984  		ret = -1;
1985  #endif
1986  
1987  	if (-1 == ret)
1988  		return;
1989  
1990  #ifdef PROJECT_SEC_CM4
1991  	if(g_charger_mode)
1992  	{
1993          boot_image_required_t pm_image = {"pm_sys", NULL, DFS_SIZE, DFS_ADDR};
1994  
1995  		/* load sp ddr boot */
1996  #ifdef CONFIG_SP_DDR_BOOT
1997  		load_sp_boot_code();
1998  #endif
1999  
2000  		/***secboot 2nd step***/
2001  		vboot_secure_process_flow_cm4(pm_image.partition);
2002          }
2003  #endif
2004  
2005  #if defined (CONFIG_SECBOOT)
2006  	/***secboot 3rd step***/
2007  	secboot_terminal();
2008  #endif
2009  
2010  	// add for SOTER start
2011  #if defined (CONFIG_CHIP_UID)
2012  	pass_chip_uid_to_tos();
2013  #endif
2014  	 // add for SOTER end
2015  
2016  //#if defined(TOS_TRUSTY) && defined(CONFIG_EMMC_BOOT) && defined(CONFIG_SPRD_RPMB)
2017  
2018  #if defined(CONFIG_SPRD_RPMB)
2019  	if(gd->boot_device == BOOT_DEVICE_EMMC) {
2020  		uboot_set_rpmb_size();
2021  		uboot_is_wr_rpmb_key();
2022  		uboot_check_rpmb_key();
2023  	}
2024  #endif
2025  
2026  #ifdef CONFIG_TEE_FIREWALL
2027  	//fdt_reserved_mem_multimedia_parse(dt_adr);
2028  #endif
2029  
2030  #if (defined CONFIG_X86) && (defined CONFIG_MOBILEVISOR) && (defined CONFIG_SPRD_SOC_SP9853I)
2031      tos_end_notify();
2032  #endif
2033  
2034  #ifdef  CONFIG_SPRD_HW_I2C
2035  	i2c_dvfs_hwchn_init();
2036  #endif
2037  
2038  	vlx_entry(dt_adr);
2039  }
2040  

kernel 启动

启动挂载分区

挂载分区过程

你可能感兴趣的:(Linux,Android)