1.先看preloader生成过程,mediatek/buid/makemtk.mk文件里
preloader: ... $(hide) cd $(PRELOADER_WD) && (./build.sh $(PROJECT) $(ACTION) $(DEAL_STDOUT) && cd $(MKTOPDIR) && $(call chkImgSize,$(ACTION),$(PROJECT),$(SCATTER_FILE),$(PRELOADER_IMAGES),$(DEAL_STDOUT),&&) $(SHOWRSLT) $$? $(MODULE_LOG) || $(SHOWRSLT) $$? $(MODULE_LOG)) ...
执行mediatek/source/preloader/build.sh生成的。
2.在build.sh里有
function build_preloader ()
{
...
make
.....
}
3.执行mediatek/source/preloader/Makefile文件的make命令。
all: $(ALL) # ELF Generation # $(D_BIN)/$(PL_IMAGE_NAME).elf: $(LD) --gc-sections -Bstatic -T$(MTK_PATH_PLATFORM)/link_descriptor.ld $(wildcard $(D_OBJ)/*) $(SECURITY_LIB) -Map system.map -o $(D_BIN)/$(PL_IMAGE_NAME).elf @$(OBJCOPY) ${OBJCFLAGS} $(D_BIN)/$(PL_IMAGE_NAME).elf -O binary $(D_BIN)/$(PL_IMAGE_NAME).bin cat $(MTK_PATH_CUSTOM)/MTK_Loader_Info.tag >> $(D_BIN)/$(PL_IMAGE_NAME).bin
这一句会最终解释为:
arm-eabi-ld --gc-sections -Bstatic -T/home/chyl411/android/alps/mediatek/platform/mt6573/preloader/link_descriptor.ld /home/chyl411/android/alps/mediatek/source/preloader/out/assembly.o /home/chyl411/android/alps/mediatek/source/preloader/out/... ............... /home/chyl411/android/alps/mediatek/platform/mt6573/preloader/src/SecLib.a -Map system.map -o /home/chyl411/android/alps/mediatek/source/preloader/bin/preloader_(工程名)_gb.elf。
用arm-eabi-ld工具配合ld文件生成最终elf。第一行/home/chyl411/android/alps/mediatek/source/preloader/out/assembly.o是指assembly.s文件。
4.assembly.s源码们于mediatekplatformmt6573preloadersrcinit目录下:
.... entry : /* Disable watch dog timer & Init CP15 setting */ BL primary_sys_init B C_Main ....
.globl JumpCmd
JumpCmd:
MOV pc, r0
最终会转入C_Main执行。源码们于同一目录下。
5.C_Main进行一些初始化之后,将uboot拷入DRAM,并跳转到UBOOT命令模式。
void C_Main (void) { SYS_BOOT_REASON reason; g_boot_mode = NORMAL_BOOT; // pre-process pl_sys_init(); // check boot reason #ifdef ENABLE_POWER_ON_VIBRATOR reason=pl_check_boot_reason(); #else pl_check_boot_reason(); #endif //boot security tactics pl_security_init(); // clear SGX core clock pl_operate_clock(); #ifdef ENABLE_POWER_ON_VIBRATOR if(reason == BR_POWER_KEY){ *(volatile unsigned short *)0x7002F7B0 |= 1 << 0 | 6 << 4; gpt4_busy_wait_ms (100); *(volatile unsigned short *)0x7002F7B0 &= ~(1 << 0); } #endif // check cable in or not and charge type meta_detection_via_usb(); #ifndef CFG_UART_HANDSHAKE_DISABLE //via UART to detect tool meta_detection_via_uart (); #endif pl_security_check(); // post process pl_post_process (); // do other function pl_do_other_function(); // load u-boot image to DRAM pl_load_uboot_image (); // jump to DRAM to run u-boot image pl_print_title ("Jump U-Boot"); JumpCmd ((UBOOT_IMG_ADDR)); while (1); }
JumpCmd函数在步骤4代码中,跳转到UBOOT_IMG_ADDR处执行。