26
2017
09

[RK3399][Android6.0] 系统支持的重启模式

Platform: Rockchip
OS: Android 6.0
Kernel: 3.10.92

系统重启过程可参考  [RK3399][Android6.0] 系统重启调用过程小结

而重启时android系统是支持带参数重启的.
rk平台上定义的boot mode如下:

enum {
    BOOT_NORMAL = 0, /* 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(0xf3030000, RK_CRU_VIRT + RK3288_CRU_MODE_CON);
    dsb();
    writel_relaxed(0xeca8, 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 & 0xFF) : 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 & 0xFFFFFF00) == 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, 0, 0, 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;
}
上一篇:多线程使用信号量sem_init,sem_wait,sem_post 下一篇:[RK3288][Android6.0] 调试笔记 --- Camera动态热插拔支持