Location:
bootloader/lk/app/aboot/aboot.c
At the end of the file is the following code:
APP_START(aboot) .init = aboot_init, APP_END
Take a look at the definition of macro app "start"
#define APP_START(appname) struct app_descriptor _app_##appname __SECTION(".apps") = { .name = #appname, #define APP_END };
Expand the above result to:
struct app_descriptor _app_aboot = { .name = aboot, .init = aboot_init, }
So where is about init called?
bootable/bootloader/lk/kernel/main.c
static int bootstrap2(void *arg){ ··· apps_init(); ··· }
Here we mainly look at the order of calls. For the detailed procedure, see the code: bootable/bootloader/lk/app/app.c
void apps_init(void) { /* call all the init routines */ for (app = &__apps_start; app != &__apps_end; app++) { if (app->init) app->init(app);//Run the about? Init function here. } }
A brief introduction to the function about init
void aboot_init(const struct app_descriptor *app) { /* Setup page size information for nv storage */ //Read the register and check whether the device is started from emmc if (target_is_emmc_boot()) { page_size = mmc_page_size(); page_mask = page_size - 1; dprintf(CRITICAL,"liyang emmc boot\n"); } //Read the properties of the device from the devinfo/aboot partition read_device_info(&device); read_allow_oem_unlock(&device); /* Display splash screen if enabled */ #if DISPLAY_SPLASH_SCREEN #if NO_ALARM_DISPLAY if (!check_alarm_boot()) { #endif //Initialize the display module, where the data in the splash partition is read and displayed. //This place hasn't been opened yet, so it hasn't been shown dprintf(CRITICAL, "Display Init: liyang Start %s\n", device.display_panel); target_display_init(device.display_panel); dprintf(CRITICAL, "Display Init: liyang Done\n"); #if NO_ALARM_DISPLAY } #endif #endif //Read the serial number of the device target_serialno((unsigned char *) sn_buf); //Open the device display here, and you can see the boot logo read from splash above qpnp_wled_set_level(gwled, QPNP_WLED_MAX_BR_LEVEL); memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE); /* * Check power off reason if user force reset, * if yes phone will do normal boot. */ if (is_user_force_reset()) goto normal_boot; //The next step is to test the buttons, and enter the upgrade or ELoad mode (tile changing) according to different combinations /* Check if we should do something other than booting up */ if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_BACK)) { //Add by Skysoft start }else if (keys_get_state(KEY_VOLUMEDOWN) && keys_get_state(KEY_BACK)) { //Add by Skysoft end }else{ } normal_boot: if (!boot_into_fastboot)//Enter the normal startup process { if (target_is_emmc_boot()) { if(emmc_recovery_init()) dprintf(CRITICAL," liyang error in emmc_recovery_init\n"); if(target_use_signed_kernel()) { if((device.is_unlocked) || (device.is_tampered)) { #ifdef TZ_TAMPER_FUSE set_tamper_fuse_cmd(); #endif #if USE_PCOM_SECBOOT set_tamper_flag(device.is_tampered); #endif } } boot_linux_from_mmc(); dprintf(CRITICAL, "liyang after boot_linux_from_mmc\n"); } else//If the upgrade process fails, it will enter this branch. { dprintf(CRITICAL, "liyang recovery_init\n"); recovery_init();//Get the upgrade status to decide whether to enter recovery/boot #if USE_PCOM_SECBOOT if((device.is_unlocked) || (device.is_tampered)) set_tamper_flag(device.is_tampered); #endif boot_linux_from_flash();//Enter recovery/boot according to recovery init } }else//Enter fastboot mode /* We are here means regular boot did not happen. Start fastboot. */ /* register aboot specific fastboot commands */ aboot_fastboot_register_commands();//Register the command in fastboot. You can also add the fastboot command from here. That is, the command is stored in a linked list of type struct fastboot? Var. /* dump partition table for debug info */ partition_dump();//Read out the partition information of the device /* initialize and start fastboot */ fastboot_init(target_get_scratch_address(), target_get_max_flash_size());//Initialize fastboot. Including the initialization of usb. #if FBCON_DISPLAY_MSG display_fastboot_menu();//Show fastboot menu #endif }
Let's take a look at the FastBoot init function, which is mainly to register some events, initialize USB, and open a Thread to detect these events.
int fastboot_init(void *base, unsigned size){ thr = thread_create("fastboot", fastboot_handler, 0, DEFAULT_PRIORITY, 4096); } static int fastboot_handler(void *arg) { for (;;) { event_wait(&usb_online); fastboot_command_loop(); } return 0; } static void fastboot_command_loop(void) { //Apply for a cache uint8_t *buffer = (uint8_t *)memalign(CACHE_LINE, ROUNDUP(4096, CACHE_LINE)); again: while (fastboot_state != STATE_ERROR) {//Start to read the data in USB, and call the previously registered processing function. r = usb_if.usb_read(buffer, MAX_RSP_SIZE); fastboot_state = STATE_COMMAND; for (cmd = cmdlist; cmd; cmd = cmd->next) { if (memcmp(buffer, cmd->prefix, cmd->prefix_len)) continue; cmd->handle((const char*) buffer + cmd->prefix_len, (void*) download_base, download_size);//cmd has been registered in the linked list in the previous introduction. The registered function is called here. if (fastboot_state == STATE_COMMAND) fastboot_fail("unknown reason"); goto again; } fastboot_fail("unknown command"); } fastboot_state = STATE_OFFLINE; dprintf(INFO,"fastboot: oops!\n"); free(buffer); }
This is the boot process.