天天看點

[RK3399][Android6.0] 系統支援的重新開機模式

Platform: Rockchip

OS: Android 6.0

Kernel: 3.10.92

系統重新開機過程可參考  [RK3399][Android6.0] 系統重新開機調用過程小結

而重新開機時android系統是支援帶參數重新開機的.

rk平台上定義的boot mode如下:

enum {
    BOOT_NORMAL = , /* normal boot */
    BOOT_LOADER,     /* enter loader rockusb mode */
    BOOT_MASKROM,    /* enter maskrom rockusb mode (not support now) */
    BOOT_RECOVER,    /* enter recover */
    BOOT_NORECOVER,  /* do not enter recover */
    BOOT_SECONDOS,   /* boot second OS (not support now)*/
    BOOT_WIPEDATA,   /* enter recover and wipe data. */
    BOOT_WIPEALL,    /* enter recover and wipe all data. */
    BOOT_CHECKIMG,   /* check firmware img with backup part(in loader mode)*/
    BOOT_FASTBOOT,   /* enter fast boot mode */
    BOOT_SECUREBOOT_DISABLE,
    BOOT_CHARGING,   /* enter charge mode */
    BOOT_MAX         /* MAX VALID BOOT TYPE.*/
};
           

而真正實作的隻有幾個常用的功能,通過rockchip_restart_get_boot_mode()來判斷是否支援.

void rockchip_restart_get_boot_mode(const char *cmd, u32 *flag, u32 *mode)
{
    *flag = SYS_LOADER_REBOOT_FLAG + BOOT_NORMAL;
    *mode = BOOT_MODE_REBOOT;

    if (cmd) {
        if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))
            *flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;
        else if(!strcmp(cmd, "recovery"))
            *flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;
        else if (!strcmp(cmd, "fastboot"))
            *flag = SYS_LOADER_REBOOT_FLAG + BOOT_FASTBOOT;
        else if (!strcmp(cmd, "charge")) {
            *flag = SYS_LOADER_REBOOT_FLAG + BOOT_CHARGING;
            *mode = BOOT_MODE_CHARGE;
        }
    } else {
        if (is_panic)
            *mode = BOOT_MODE_PANIC;
    }
}
           

支援的boot flag被儲存在固定位置

#define SYS_LOADER_REBOOT_FLAG 0x5242C300 //high 24 bits is tag, low 8 bits is type

reboot之前通過rk3288_restart()寫到寄存器RK3288_PMU_SYS_REG0中.

static void rk3288_restart(char mode, const char *cmd)
{
    u32 boot_flag, boot_mode;

    rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);

    writel_relaxed(boot_flag, RK_PMU_VIRT + RK3288_PMU_SYS_REG0);   // for loader
    writel_relaxed(boot_mode, RK_PMU_VIRT + RK3288_PMU_SYS_REG1);   // for linux
    dsb();

    /* pll enter slow mode */
    writel_relaxed(xf3030000, RK_CRU_VIRT + RK3288_CRU_MODE_CON);
    dsb();
    writel_relaxed(xeca8, RK_CRU_VIRT + RK3288_CRU_GLB_SRST_SND_VALUE);
    dsb();
}
           

reboot的時候在uboot中判斷boot flag

enum fbt_reboot_type board_fbt_get_reboot_type(void)
{
    enum fbt_reboot_type frt = FASTBOOT_REBOOT_UNKNOWN;

    uint32_t loader_flag = IReadLoaderFlag();
    int reboot_mode = loader_flag ? (loader_flag & ) : BOOT_NORMAL;

    /* Feedback reboot mode to the kernel. */
    ISetLoaderFlag(SYS_KERNRL_REBOOT_FLAG | reboot_mode);


    if (SYS_LOADER_ERR_FLAG == loader_flag) {
        loader_flag = SYS_LOADER_REBOOT_FLAG | BOOT_LOADER;
        reboot_mode = BOOT_LOADER;
    }

    if ((loader_flag & ) == SYS_LOADER_REBOOT_FLAG) {
        switch (reboot_mode) {
        case BOOT_NORMAL:
            printf("reboot normal.\n");
            frt = FASTBOOT_REBOOT_NORMAL;
            break;
        case BOOT_LOADER:
#ifdef CONFIG_CMD_ROCKUSB
            printf("reboot rockusb.\n");
            do_rockusb(NULL, , , NULL);
#endif
            break;
#ifdef CONFIG_CMD_FASTBOOT
        case BOOT_FASTBOOT:
            printf("reboot fastboot.\n");
            frt = FASTBOOT_REBOOT_FASTBOOT;
            break;
#endif
        case BOOT_NORECOVER:
            printf("reboot no recover.\n");
            frt = FASTBOOT_REBOOT_NORECOVER;
            break;
        case BOOT_RECOVER:
            printf("reboot recover.\n");
            frt = FASTBOOT_REBOOT_RECOVERY;
            break;
        case BOOT_WIPEDATA:
        case BOOT_WIPEALL:
            printf("reboot wipe data.\n");
            frt = FASTBOOT_REBOOT_RECOVERY_WIPE_DATA;
            break;
        case BOOT_CHARGING:
            printf("reboot charge.\n");
            frt = FASTBOOT_REBOOT_CHARGE;
            break;
        default:
            printf("unsupport reboot type %d\n", reboot_mode);
            break;
        }
    } else {
        printf("normal boot.\n");
    }

......
    return frt;
}