void bootcount_store(unsigned long bootcount) { if (running_from_sd()) { return; } printf("BootCnt %lu\n", bootcount); if (bootcount > ACCLAIM_BOOTLIMIT) { // In case we have reached the bootlimit // we write the factory restore bcb write_bcb(&factory_bcb); // and to prevent us from applying the factory // fallback for infinity we clear it before entering recovery bootcount = 0; } sprintf(buf, "mmcinit 1; fatsave mmc 1:5 0x%08x BootCnt", &bootcount); if (run_command(buf, 0)) { printf("Cannot write BootCnt, rom restore forced.\n"); write_bcb(&romrestore_bcb); } }
unsigned long bootcount_load(void) { if (running_from_sd()) { return 0; } unsigned long bootcount = ACCLAIM_BOOTLIMIT + 1; // Set bootcount to limit+1 per default, in case we fail to read it apply factory fallback sprintf(buf, "mmcinit 1; fatload mmc 1:5 0x%08x BootCnt 4", &bootcount); if (run_command(buf, 0)) { printf("No BootCnt found, rom restore forced.\n"); write_bcb(&romrestore_bcb); } return bootcount; }
void do_factory_fallback(void) { write_bcb(&factory_bcb); run_command("mmcinit 1; booti mmc1 recovery", 0); }
static inline enum boot_action get_boot_action(void) { static struct bootloader_message update_bcb = { .command = "boot-recovery", .status = "", .recovery = "", }; static const struct bootloader_message master_clear_bcb = { .command = "boot-recovery", .status = "", .recovery = "recovery\n--wipe_data_ui\n", }; volatile unsigned int *reset_reason = (unsigned int *) 0x4A307B04; volatile struct bootloader_message *bcb = (struct bootloader_message *) 0x81000000; static const char reboot_panic[] = "reboot\0panic"; u8 pwron = 0; int update_zip; if (!memcmp((const char *) PUBLIC_SAR_RAM_1_FREE, reboot_panic, sizeof(reboot_panic))) { printf("REBOOT DUE TO KERNEL PANIC!\n"); } // First check for sd boot if (running_from_sd()) { printf("Booting from sd\n"); return BOOT_SD; } if (mmc_init(1)) { printf("mmc_init failed!\n"); return INVALID; } if (load_serial_num()) { printf("No serialnum found, rom restore forced.\n"); write_bcb(&romrestore_bcb); return RECOVERY; } fastboot_flash_dump_ptn(); // Then check if there's a BCB file if (!read_bcb()) { printf("BCB found, checking...\n"); if (bcb->command[0] != 0 && bcb->command[0] != 255) { printf("Booting into recovery\n"); return RECOVERY; } } else { printf("No BCB found, recovery mode forced.\n"); return RECOVERY; } // If cold reboot/start if (!(*reset_reason & WARM_RESET) && strcmp((const char *) PUBLIC_SAR_RAM_1_FREE, "reboot")) { // Then check for update zip on sd update_zip = check_update_zip(); if (update_zip >= 0 && update_zip < ARRAY_SIZE(update_zip_names)) { sprintf(update_bcb.recovery, "recovery\n--update_package=/sdcard/%s\n--update_factory\n", update_zip_names[update_zip]); write_bcb(&update_bcb); printf("Found %s, booting into recovery\n", update_zip_names[update_zip]); return RECOVERY; } } else if (!strcmp((const char *) PUBLIC_SAR_RAM_1_FREE, "recovery")) { printf("Rebooted with recovery reason, booting into recovery\n"); return RECOVERY; } if (twl6030_hw_status(&pwron)) { printf("Failed to read twl6030 hw_status\n"); } // Check master clear button press combination (power+home) // note that home button is inverted if ((gpio_read(HOME_BUTTON) == 0) && (pwron & STS_PWRON) != STS_PWRON) { printf("Master Clear forced, booting into recovery\n"); write_bcb(&master_clear_bcb); return RECOVERY; } printf("Booting into Android\n"); return BOOT_EMMC; } int determine_boot_type(void) { setenv("bootlimit", stringify(ACCLAIM_BOOTLIMIT)); setenv("altbootcmd", "mmcinit 1; booti mmc1 recovery"); switch(get_boot_action()) { case BOOT_SD: setenv ("bootcmd", "setenv setbootargs setenv bootargs ${sdbootargs}; run setbootargs; mmcinit 0; fatload mmc 0:1 0x81000000 flashing_boot.img; booti 0x81000000"); setenv ("altbootcmd", "run bootcmd"); // for sd boot altbootcmd is the same as bootcmd break; case RECOVERY: setenv("bootcmd", "mmcinit 1; booti mmc1 recovery"); break; case BOOT_EMMC: setenv("bootcmd", "mmcinit 1; booti mmc1 boot"); break; case INVALID: default: printf("Aborting boot!\n"); return 1; } return 0; }