ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2013年11月26日 星期二

kernel reboot

以 arm 來看..
arch/arm/kernel/process.c:
void arm_machine_restart(char mode, const char *cmd)
{
        .....

        /*
         * Now call the architecture specific reboot code.
         */
        arch_reset(mode, cmd);
這個 arch_reset( ),是 implement 在 mach/system.h
mach 是在 arch/arm/mach-XXX/include 下。

所以每一個 mach-XXX 都有自己的 implememt。



往上看..
void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
..
void machine_restart(char *cmd)
{
        machine_shutdown();
        arm_pm_restart(reboot_mode, cmd);
}

這是在 kernel/sys.c 中呼叫:
void kernel_restart(char *cmd)
{
        kernel_restart_prepare(cmd);
        if (!cmd)
                printk(KERN_EMERG "Restarting system.\n");
        else
                printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
        kmsg_dump(KMSG_DUMP_RESTART);
        machine_restart(cmd);
}
EXPORT_SYMBOL_GPL(kernel_restart);

然後是這個:
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
                void __user *, arg)
{
        ...
        switch (cmd) {
        case LINUX_REBOOT_CMD_RESTART:
                kernel_restart(NULL);
                break;
        ...
        case LINUX_REBOOT_CMD_RESTART2:
                if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
                        ret = -EFAULT;
                        break;
                }
                buffer[sizeof(buffer) - 1] = '\0';

                kernel_restart(buffer);
                break;
        ...
轉成 syscall 介面 (reboot)


User Space: bionic

libc/include/sys/reboot.h
extern int reboot(int  reboot_type);
extern int __reboot(int, int, int, void *);

在 android framework 中..
framework/base/core/jni/android_os_Power.cpp:
static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
{
    sync();
#ifdef HAVE_ANDROID_OS
    if (reason == NULL) {
        reboot(RB_AUTOBOOT);
    } else {
        const char *chars = env->GetStringUTFChars(reason, NULL);
        __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                 LINUX_REBOOT_CMD_RESTART2, (char*) chars);
        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.
    }
    jniThrowIOException(env, errno);
#endif
}

沒有留言:

標籤

網誌存檔