Recovery启动流程(1)--- 应用层到开机进入recovery详解

  进入recovery有两种方式,一种是通过组合键进入recovery,另一种是上层应用设置中执行安装/重置/清除缓存等操作进行recovery。这篇文档主要讲解上层应用是如何进入到recovery的。本文以高通平台为例。

  

1.app执行安装/重置/清楚缓存操作调用代码文件frameworks/base/core/java/android/os/RecoverySystem.java

不同的操作使用不同的方法:

安装升级包  --------  installPackage

清除用户数据------  rebootWipeUserData

清楚缓存  -----------  rebootWipeCache

上面的所有操作都是往/cache/recovery/command文件中写入不同的命令,在进入recovery后(recovery.cpp)对command的关键字进行判断,执行相应的操作,下文会详细讲解,这里先简单提及。

bootable/recovery/recovery.appstatic const struct option OPTIONS[] = {
  { "send_intent", required_argument, NULL, ‘i‘ },
  { "update_package", required_argument, NULL, ‘u‘ },
// [FEATURE]-ADD-BEGIN by TCTSH
#ifdef TARGET_USE_REDBEND_FOTA
  { "omadm_package", required_argument, NULL, ‘o‘ },
#endif
// [FEATURE]-ADD-END
  { "wipe_data", no_argument, NULL, ‘w‘ },
  { "wipe_cache", no_argument, NULL, ‘c‘ },
  { "show_text", no_argument, NULL, ‘t‘ },
  { "sideload", no_argument, NULL, ‘s‘ },
  { "sideload_auto_reboot", no_argument, NULL, ‘a‘ },
  { "just_exit", no_argument, NULL, ‘x‘ },
  { "locale", required_argument, NULL, ‘l‘ },
  { "stages", required_argument, NULL, ‘g‘ },
  { "shutdown_after", no_argument, NULL, ‘p‘ },
  { "reason", required_argument, NULL, ‘r‘ },
  { NULL, 0, NULL, 0 },
};

..................

intmain(int argc, char **argv) {....get_args(&argc, &argv); //提取cache/recovery/command中的信息....while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {      //解析cache/recovery/command文件中的信息        printf("***** xiaolei 2\n");        switch (arg) {        case ‘i‘: send_intent = optarg; break;        case ‘u‘: update_package = optarg; break;// [FEATURE]-ADD-BEGIN by TCTSH

        case ‘o‘: omadm_package = optarg; break;

// [FEATURE]-ADD-END        case ‘w‘: should_wipe_data = true; break;        case ‘c‘: should_wipe_cache = true; break;        case ‘t‘: show_text = true; break;        case ‘s‘: sideload = true; break;        case ‘a‘: sideload = true; sideload_auto_reboot = true; break;        case ‘x‘: just_exit = true; break;        case ‘l‘: locale = optarg; break;        case ‘g‘: {            if (stage == NULL || *stage == ‘\0‘) {                char buffer[20] = "1/";                strncat(buffer, optarg, sizeof(buffer)-3);                stage = strdup(buffer);            }            break;        }        case ‘p‘: shutdown_after = true; break;        case ‘r‘: reason = optarg; break;        case ‘?‘:            LOGE("Invalid command argument\n");            continue;        }    }}

本文以installPackage为例:

frameworks/base/core/java/android/os/RecoverySystem.javapublic static void installPackage(Context context, File packageFile)
        throws IOException {
        String filename = packageFile.getCanonicalPath();    //获取升级包路径
        String internalPath = Environment.maybeTranslateEmulatedPathToInternal(new File(filename)).getPath();
        FileWriter uncryptFile = new FileWriter(UNCRYPT_FILE);
        try {
            uncryptFile.write(internalPath + "\n");
        } finally {
            uncryptFile.close();
        }
        Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
        Log.w(TAG, "!!! REBOOTING TO INSTALL REALPATH " + internalPath + " !!!");

        // If the package is on the /data partition, write the block map file
        // If the package is on internal storage sdcard,write the block map file
        // into COMMAND_FILE instead.
        if (filename.startsWith("/data/")                           //加密处理,block.map是解密的映射文件
                ||filename.startsWith("/storage/emulated/0/")) {
            filename = "@/cache/recovery/block.map";
        }

        final String filenameArg = "--update_package=" + filename;     //把“--update_package=path” 通过bootCommand方法写入到cache/recovery/command文件中
        final String localeArg = "--locale=" + Locale.getDefault().toString();  //recovery显示语言
        bootCommand(context, filenameArg, localeArg);
    }
installPackage方法会嗲用bootCommand()方法,此时参数为(context,向cache/recovery/command文件中写入的信息,语言信息)
private static void bootCommand(Context context, String... args) throws IOException {
        RECOVERY_DIR.mkdirs();  // In case we need it
        COMMAND_FILE.delete();  // In case it‘s not writable
        LOG_FILE.delete();

        FileWriter command = new FileWriter(COMMAND_FILE);     //向/cache/recovery/command中写入--update_package=path
        try {
            for (String arg : args) {
                if (!TextUtils.isEmpty(arg)) {
                    command.write(arg);
                    command.write("\n");
                }
            }
        } finally {
            command.close();
        }

        // Having written the command file, go ahead and reboot
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        pm.reboot(PowerManager.REBOOT_RECOVERY);  //PowerManager.REBOOT_RECOVERY的值为字符串"recovery"

        throw new IOException("Reboot failed (no permissions?)");
    }
pm.reboot(PowerManager.REBOOT_RECOVERY); 参数为字符串("recovery")
frameworks/base/core/java/android/os/PowerMangager.java

public void reboot(String reason) {
        try {
            mService.reboot(false, reason, true);
        } catch (RemoteException e) {
        }
    }

 mService.reboot(false, reason, true);    参数为(false,"recovery",true)
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void reboot(boolean confirm, String reason, boolean wait) {       
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
            if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
            }

            final long ident = Binder.clearCallingIdentity();
            try {
                shutdownOrRebootInternal(false, confirm, reason, wait);      
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }
shutdownOrRebootInternal(false, confirm, reason, wait);  参数为(false,false,"recovery",true)

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
            final String reason, boolean wait) {
        if (mHandler == null || !mSystemReady) {
            throw new IllegalStateException("Too early to call shutdown() or reboot()");
        }

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    if (shutdown) {                   //此处shutdown=false
                        ShutdownThread.shutdown(mContext, confirm);
                    } else {
                        ShutdownThread.reboot(mContext, reason, confirm);   //执行此处代码
                    }
                }
            }
        };

        // ShutdownThread must run on a looper capable of displaying the UI.
        Message msg = Message.obtain(mHandler, runnable);
        msg.setAsynchronous(true);
        mHandler.sendMessage(msg);

        // PowerManager.reboot() is documented not to return so just wait for the inevitable.
        if (wait) {
            synchronized (runnable) {
                while (true) {
                    try {
                        runnable.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }
ShutdownThread.reboot(mContext, reason, confirm); 参数为(mContex,"recovery",false)此处开了一个线程处理reboot
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java

public static void reboot(final Context context, String reason, boolean confirm) {        //方法中的变量为全局变量
        mReboot = true;
        mRebootSafeMode = false;
        mRebootUpdate = false;
        mRebootReason = reason;
        shutdownInner(context, confirm);       //此方法是在手机界面上弹出一个确认框,是否重启,此处的代码不再追了
    }

//程序一定会执行run()方法

/***********************
mReboot = true;
mRebootSafeMode = false;
mRebootUpdate = false;
mRebootReason = "recovery";***********************/public void run() {        BroadcastReceiver br = new BroadcastReceiver() {            @Override public void onReceive(Context context, Intent intent) {                // We don‘t allow apps to cancel this, so ignore the result.                actionDone();            }        };

        /*         * Write a system property in case the system_server reboots before we         * get to the actual hardware restart. If that happens, we‘ll retry at         * the beginning of the SystemServer startup.         */        {            String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");     //reason的值为"recovery"            SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);  //设置系统属性sys.shutdown.requested = "recovery"        }

        /*         * If we are rebooting into safe mode, write a system property         * indicating so.         */        if (mRebootSafeMode) {            SystemProperties.set(REBOOT_SAFEMODE_PROPERTY, "1");        }

        Log.i(TAG, "Sending shutdown broadcast...");        // [BUGFIX]-ADD-BEGIN BY TCTNB.BinhongWang,01/28/2016,Defect-1305415        setBootValue("silent_mode",mAudioManager.isSilentMode() ? "1" : "0");        if(checkAnimationFileExist() && mContext.getResources().                getBoolean(com.android.internal.R.bool.feature_tctfw_shutdown_animation_on) &&                !mRebootUpdate) {            lockDevice();            showShutdownAnimation();        }        // [BUGFIX]-ADD-END BY TCTNB.BinhongWang,01/28/2016,Defect-1305415

        // First send the high-level shut down broadcast.        mActionDone = false;        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);        mContext.sendOrderedBroadcastAsUser(intent,                UserHandle.ALL, null, br, mHandler, 0, null, null);

        final long endTime = SystemClock.elapsedRealtime() + MAX_BROADCAST_TIME;        synchronized (mActionDoneSync) {            while (!mActionDone) {                long delay = endTime - SystemClock.elapsedRealtime();                if (delay <= 0) {                    Log.w(TAG, "Shutdown broadcast timed out");                    break;                } else if (mRebootUpdate) {                    int status = (int)((MAX_BROADCAST_TIME - delay) * 1.0 *                            BROADCAST_STOP_PERCENT / MAX_BROADCAST_TIME);                    sInstance.setRebootProgress(status, null);                }                try {                    mActionDoneSync.wait(Math.min(delay, PHONE_STATE_POLL_SLEEP_MSEC));                } catch (InterruptedException e) {                }            }        }        if (mRebootUpdate) {            sInstance.setRebootProgress(BROADCAST_STOP_PERCENT, null);        }        Log.i(TAG, "Shutting down activity manager...");

        final IActivityManager am =            ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));        if (am != null) {            try {                am.shutdown(MAX_BROADCAST_TIME);            } catch (RemoteException e) {            }        }        if (mRebootUpdate) {            sInstance.setRebootProgress(ACTIVITY_MANAGER_STOP_PERCENT, null);        }

        Log.i(TAG, "Shutting down package manager...");

        final PackageManagerService pm = (PackageManagerService)            ServiceManager.getService("package");        if (pm != null) {            pm.shutdown();        }        if (mRebootUpdate) {            sInstance.setRebootProgress(PACKAGE_MANAGER_STOP_PERCENT, null);        }

        // Shutdown radios.        shutdownRadios(MAX_RADIO_WAIT_TIME);        if (mRebootUpdate) {            sInstance.setRebootProgress(RADIO_STOP_PERCENT, null);        }

        // Mod-by-yanxi.liu, for sdcard upgrade uncrypt, Defect-1357392        if (mRebootUpdate) {            sInstance.setRebootProgress(MOUNT_SERVICE_STOP_PERCENT, null);            // If it‘s to reboot to install update, invoke uncrypt via init service.            uncrypt();        }        // Mod-by-yanxi.liu, for sdcard upgrade uncrypt, Defect-1357392

        // Shutdown MountService to ensure media is in a safe state        IMountShutdownObserver observer = new IMountShutdownObserver.Stub() {            public void onShutDownComplete(int statusCode) throws RemoteException {                Log.w(TAG, "Result code " + statusCode + " from MountService.shutdown");                actionDone();            }        };

        Log.i(TAG, "Shutting down MountService");

        // Set initial variables and time out time.        mActionDone = false;        final long endShutTime = SystemClock.elapsedRealtime() + MAX_SHUTDOWN_WAIT_TIME;        synchronized (mActionDoneSync) {            try {                final IMountService mount = IMountService.Stub.asInterface(                        ServiceManager.checkService("mount"));                if (mount != null) {                    mount.shutdown(observer);                } else {                    Log.w(TAG, "MountService unavailable for shutdown");                }            } catch (Exception e) {                Log.e(TAG, "Exception during MountService shutdown", e);            }            while (!mActionDone) {                long delay = endShutTime - SystemClock.elapsedRealtime();                if (delay <= 0) {                    Log.w(TAG, "Shutdown wait timed out");                    break;                } else if (mRebootUpdate) {                    int status = (int)((MAX_SHUTDOWN_WAIT_TIME - delay) * 1.0 *                            (MOUNT_SERVICE_STOP_PERCENT - RADIO_STOP_PERCENT) /                            MAX_SHUTDOWN_WAIT_TIME);                    status += RADIO_STOP_PERCENT;                    sInstance.setRebootProgress(status, null);                }                try {                    mActionDoneSync.wait(Math.min(delay, PHONE_STATE_POLL_SLEEP_MSEC));                } catch (InterruptedException e) {                }            }        }        // add by feikuang for defect 1453123 start        isVibrate = mContext.getResources().getBoolean(com.android.internal.R.bool.config_isVibrate);        Log.i(TAG,"isVibrate " + isVibrate);        // add by feikuang for defect 1453123 end        waitShutDownAnimationCompleted();        rebootOrShutdown(mContext, mReboot, mRebootReason);        //程序执行到这里    }
rebootOrShutdown(mContext, mReboot, mRebootReason); 参数为(mContext,true,"recovery")
frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
public static void rebootOrShutdown(final Context context, boolean reboot, String reason) {
        deviceRebootOrShutdown(reboot, reason);
        //[FEATURE]-Add-BEGIN by TSNJ.shu.wang,11/06/2015,TASK-871146
        String bootAlarms = SystemProperties.get("sys.boot.alarm");
        boolean isBootAlarms = bootAlarms != null && bootAlarms.equals("1");
        if (reboot) {
            Log.i(TAG, "Rebooting, reason: " + reason);
            PowerManagerService.lowLevelReboot(reason);           //程序执行到这里
            Log.e(TAG, "Reboot failed, will attempt shutdown instead");
        } else if (SHUTDOWN_VIBRATE_MS > 0 && context != null && !isBootAlarms && isVibrate) {
        //[FEATURE]-Add-END by TSNJ.shu.wang,11/06/2015,TASK-871146
            // vibrate before shutting down
            Vibrator vibrator = new SystemVibrator(context);
            try {
                vibrator.vibrate(SHUTDOWN_VIBRATE_MS, VIBRATION_ATTRIBUTES);
            } catch (Exception e) {
                // Failure to vibrate shouldn‘t interrupt shutdown.  Just log it.
                Log.w(TAG, "Failed to vibrate during shutdown.", e);
            }

            // vibrator is asynchronous so we need to wait to avoid shutting down too soon.
            try {
                Thread.sleep(SHUTDOWN_VIBRATE_MS);
            } catch (InterruptedException unused) {
            }
        }

        // Shutdown power
        Log.i(TAG, "Performing low-level shutdown...");
        PowerManagerService.lowLevelShutdown();
    }
PowerManagerService.lowLevelReboot(reason);  参数为"recovery"
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public static void lowLevelReboot(String reason) {
        if (reason == null) {
            reason = "";
        }
        if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
            // If we are rebooting to go into recovery, instead of
            // setting sys.powerctl directly we‘ll start the
            // pre-recovery service which will do some preparation for
            // recovery and then reboot for us.
            SystemProperties.set("ctl.start", "pre-recovery");    //到这里可以知道,一个新的进程会被enable
        } else {
            SystemProperties.set("sys.powerctl", "reboot," + reason);
        }
        try {
            Thread.sleep(20 * 1000L);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        Slog.wtf(TAG, "Unexpected return from lowLevelReboot!");
    }
SystemProperties.set("ctl.start", "pre-recovery");    //到这里可以知道,一个新的进程会被enable
system/core/rootdir/init.rc
service pre-recovery /system/bin/uncrypt --reboot  
    class main
    disabled
    oneshot

service pre-recovery /system/bin/uncrypt --reboot    system/bin/uncrypt 这个程序会被执行,传入的参数是--rebootuncrypt的源码位于bootable/recovery/uncrypt/uncrypt.cpp,下面对uncrypt进行分析
bootable/recovery/uncrypt/uncrypt.cppint main(int argc, char** argv) {          //此处argc为2  argv[1]="--reboot"
    const char* input_path;
    const char* map_file;

    if (argc != 3 && argc != 1 && (argc == 2 && strcmp(argv[1], "--reboot") != 0)) {
        fprintf(stderr, "usage: %s [--reboot] [<transform_path> <map_file>]\n", argv[0]);
        return 2;
    }

    // When uncrypt is started with "--reboot", it wipes misc and reboots.
    // Otherwise it uncrypts the package and writes the block map.
    if (argc == 2) {   //程序执行到此处
        if (read_fstab() == NULL) {  
            return 1;
        }
        wipe_misc();        //擦出misc分区内容
        reboot_to_recovery();  //重启到recovery
    } else {
        // The pipe has been created by the system server.
        int status_fd = open(status_file.c_str(), O_WRONLY | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR);
        if (status_fd == -1) {
            ALOGE("failed to open pipe \"%s\": %s\n", status_file.c_str(), strerror(errno));
            return 1;
        }
        std::string package;
        if (argc == 3) {
            // when command-line args are given this binary is being used
            // for debugging.
            input_path = argv[1];
            map_file = argv[2];
        } else {
            if (!find_uncrypt_package(package)) {
                android::base::WriteStringToFd("-1\n", status_fd);
                close(status_fd);
                return 1;
            }
            input_path = package.c_str();
            map_file = cache_block_map.c_str();
        }

        int status = uncrypt(input_path, map_file, status_fd);
        if (status != 0) {
            android::base::WriteStringToFd("-1\n", status_fd);
            close(status_fd);
            return 1;
        }

        android::base::WriteStringToFd("100\n", status_fd);
        close(status_fd);
    }

    return 0;
}
reboot_to_recovery();
bootable/recovery/uncrpty/uncrpty.cpp
static void reboot_to_recovery() {
    ALOGI("rebooting to recovery");
    property_set("sys.powerctl", "reboot,recovery");
    sleep(10);
    ALOGE("reboot didn‘t succeed?");
}

property_set("sys.powerctl", "reboot,recovery");     sys.powerctl属性出发开关在init.rc中
system/core/rootdir/init.rc
on property:sys.powerctl=*
    powerctl ${sys.powerctl}
system/core/init/keywords.hKEYWORD(powerctl,    COMMAND, 1, do_powerctl
system/core/init/builtins.cpp               
int do_powerctl(int nargs, char **args)           //传入的参数为字符串"reboot,recovery"
{
    char command[PROP_VALUE_MAX];
    int res;
    int len = 0;
    int cmd = 0;
    const char *reboot_target;

    res = expand_props(command, args[1], sizeof(command));
    if (res) {
        ERROR("powerctl: cannot expand ‘%s‘\n", args[1]);
        return -EINVAL;
    }

    if (strncmp(command, "shutdown", 8) == 0) {
        cmd = ANDROID_RB_POWEROFF;
        len = 8;
    } else if (strncmp(command, "reboot", 6) == 0) {    //程序走到这,cmd=ANDROID_RB_RESTART2
        cmd = ANDROID_RB_RESTART2;
        len = 6;
    } else {
        ERROR("powerctl: unrecognized command ‘%s‘\n", command);
        return -EINVAL;
    }

    if (command[len] == ‘,‘) {
        char prop_value[PROP_VALUE_MAX] = {0};
        reboot_target = &command[len + 1];    //设置reboot_target = recovery

        if ((property_get("init.svc.recovery", prop_value) == 0) &&
            (strncmp(reboot_target, "keys", 4) == 0)) {
            ERROR("powerctl: permission denied\n");
            return -EINVAL;
        }
    } else if (command[len] == ‘\0‘) {
        reboot_target = "";
    } else {
        ERROR("powerctl: unrecognized reboot target ‘%s‘\n", &command[len]);
        return -EINVAL;
    }

    return android_reboot(cmd, 0, reboot_target);    
}
android_reboot(cmd, 0, reboot_target);    参数为(ANDROID_RB_RESTART2, 0, "recovery")
system/core/libcutils/android_reboot.c
int android_reboot(int cmd, int flags UNUSED, const char *arg)
{
    int ret;

    sync();
    remount_ro();

    switch (cmd) {
        case ANDROID_RB_RESTART:
            ret = reboot(RB_AUTOBOOT);
            break;

        case ANDROID_RB_POWEROFF:
            ret = reboot(RB_POWER_OFF);
            break;

        case ANDROID_RB_RESTART2:             //程序跑到这里其中arg="recovery"
            ret = syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                           LINUX_REBOOT_CMD_RESTART2, arg);
            break;

        default:
            ret = -1;
    }

    return ret;
}
ret = syscall(__NR_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                           LINUX_REBOOT_CMD_RESTART2, arg);
kernel/include/uapi/asm-generic/unistd.h
#define __NR_reboot 142
__SYSCALL(__NR_reboot, sys_reboot)

__NR_reboot被映射到sys_reboot上



 

 
时间: 2024-11-10 18:32:52

Recovery启动流程(1)--- 应用层到开机进入recovery详解的相关文章

SpringBoot启动机制(starter机制)核心原理详解

作者:MyBug 一.前言 使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过程,这次主要是分析springboot特性自动装配.那么首先带领大家回顾一下以往我们的web项目是如何搭建的,通常我们要搭建一个基于Spring的Web应用,我们需要做以下一些工作:pom文件中引入相关jar包,包括spring.springmvc.redis.mybaits.l

android logo、android开机动画改变详解

android logo:内核.android开机动画 android开logo,这一块在工作改动的也是比较多的,也比较简单,不同的公司,不同型号的产品,开机的标识不一样. 我们平时目测的开机logo一般是两种:静态的和动画的.其实在实现logo的过程中,有四幅图片:(1).uboot显示:(2).kernel显示logo_linux_clut244.ppm:(3).android第一幅intilogo.rle:(4).android第二幅,bootanimation.前三幅一般我们做成相同的,

第六章 应用层(DNS和http协议详解)

序言 这是计算机网络基础的最后一篇博文了,大体的从物理层到最上层的应用层做了一个大概的了解,花了也有快1个月的时间了,在本章结尾会给你们我学习该课程的视频资料,我希望能帮到所有想学习想提高自己技术的同学,我看到很多厉害的的博客的文章都被锁了,我希望高手度能够帮助刚成长并且想努力提高技术的人.所以等我以后牛逼了,肯定会帮助哪些迷茫的人,因为自己曾经迷茫过,走了很多弯路. --WH 一.回顾 1.OSI体系结构分为7层:物理层.链路层.网路层.传输层.会话层.表示层.应用层. 2.TCP/IP的体系

Linux 开机自启动脚本详解

以kibana为例 ? ? 以下为skibana名称的脚本内容 #!/bin/bash #chkconfig: 2345 80 90 #description:kibana kibana="/usr/mysoft/kibana-4.4.1-linux-x64/bin/kibana" ? ? $kibana # daemon kibana echo "kibana4.4.1 service is started..." esac ? ? 如果是在windows上创建的

dmesg显示开机信息命令详解

dmesg    显示开机信息 kernel会将开机信息存储在ring buffer中,如果开机时来不及看,可以利用dmeg查看. 路径/var/log/dmesg 常用参数: -c    显示信息后,清楚ring buffer中内容 -s<缓存区大小>    预设值是8196,刚好等于ring buffer大小 -n    设置记录信息的层级 实例: 1-将开机信息邮件发送 man dmesg 写道The program helps users to print out their boot

CentOS 6开机启动流程实验篇

CentOS 6开机启动流程实验篇 centos 系统的启动流程 grub 破坏Linux的核心文件再修复体验系统启动流程 CentOS 6开机启动的具体详情请参见理论篇! 了解了系统启动的基本流程,以下我们通过"破坏式实验",即破坏系统启动过程中的一些关键环节,使系统无法启动,然后我们再通过修复这些文件使得系统正常重启,进而体验Linux系统的启动流程,这些关键环节包括破坏grub三个stage(stage1.stage1-5.stage2) 中的任何一个阶段,甚至是整个grub;

CentOS开机启动流程简介

我们都知道按下电脑电源键后,屏幕上会一闪而过很多信息,然后显示登录界面,然后输入用户名,密码就可以畅享网络世界了.那么这中间到底发生了什么呢,今天就让我们来简单探讨一下CentOS的简易版开机启动流程吧. 第一阶段:通电自检过程 我们都知道电脑所有数据指令都是在内存上才能被cpu处理的吧,我们还知道内存在断电后其上面的所有数据都会丢失吧,那么开机的时候内存应该是没有东西的吧,那上面都不能干了,更别说启动一个操作系统了,其实啊,我们内存并不只是我们常见的那个内存卡,很多硬件都会映射一段内存到cpu

redhat 5开机启动流程详解

(1)POST(Power On Self Test) 加电自检 电脑主机打开电源的时候随后会听到滴的一声响系统启动开始了开机自检POST. 自检开始这个过程中主要是检测计算机硬件设备比如CPU内存主板显卡等设备是否有故障存在.如果有硬件故障的话将按两种情况理对于严重故障(致命性故障)则停机此时由于各种初始化操作还没完成不能给出任何提示或信号对于非严重故障则给出提示或声音报警信号等待用户处理如果没有故障POST完成自己的接力任务将尾部工作交接给BIOS处理. (2)BIOS(bootloader

linux系统下开机启动流程

在了解开机启动流程之前,还是得先了解一些磁盘的基本知识.磁盘主要由盘片,机械手臂,磁头,主轴马达构成.盘片就是存储数据的物理单位了.然后盘片上我们可以分成扇区(sector)和柱面(cylinder),每个扇区sector为512Bytes.如下图所示: 磁盘在分区完成之后,每个分区(文件系统)都有一个启动扇区(boot sector),而开机时用到的则是整个磁盘的第一个扇区,这个扇区非常主要,构成如下: (1)主引导分区(MBR)master boot record:446Bytes:系统安装