上文:http://www.cnblogs.com/long123king/p/3549701.html

   1: static int __init kernel_init(void * unused)

   2: {

   3:  ......

   4:  

   5:     if (!ramdisk_execute_command)

   6:         ramdisk_execute_command = "/init";

   7:  

   8:     if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {

   9:         ramdisk_execute_command = NULL;

  10:         prepare_namespace();

  11:     }

  12:  

  13:     /*

  14:      * Ok, we have completed the initial bootup, and

  15:      * we're essentially up and running. Get rid of the

  16:      * initmem segments and start the user-mode stuff..

  17:      */

  18:  

  19:     init_post();

  20:     return 0;

  21: }

如何在Source Insight中查找sys_access在哪里,直接找是找不到了,不如通过”Ctrl + /”来全局查找,查找:

   1: SYSCALL_DEFINE2(access

这里面是对/init做一下检测,看看是否存在该文件,sys_access用来检测是否有权限访问该文件。

返回值不为0,代表无法访问该文件,就执行prepare_namespace另作准备。

如果这里可以访问/init文件,那么就直接调用该文件来进行初始化设置。

因此,可以推测,prepare_namespace与initrd中的/init的作用类似。


   1: /*

   2:  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.

   3:  */

   4: void __init prepare_namespace(void)

   5: {

注释的意思,决定挂载点,加载内存盘。

   1: if (root_delay) {

   2:         printk(KERN_INFO "Waiting %dsec before mounting root device...\n",

   3:                root_delay);

   4:         ssleep(root_delay);

   5:     }

是用来在挂载根文件系统之前,等待某些比较慢的IO设备准备好根设备。

root_device_name就是我们在grub中通过root=/dev/sda1设置的根文件设备。

   1: static int __init root_dev_setup(char *line)

   2: {

   3:     strlcpy(saved_root_name, line, sizeof(saved_root_name));

   4:     return 1;

   5: }

   6:  

   7: __setup("root=", root_dev_setup);

   1: if (saved_root_name[0]) {

   2:     root_device_name = saved_root_name;

   3:     if (!strncmp(root_device_name, "mtd", 3) ||

   4:         !strncmp(root_device_name, "ubi", 3)) {

   5:         mount_block_root(root_device_name, root_mountflags);

   6:         goto out;

   7:     }

   8:     ROOT_DEV = name_to_dev_t(root_device_name);

   9:     if (strncmp(root_device_name, "/dev/", 5) == 0)

  10:         root_device_name += 5;

  11: }

对于root=/dev/sda1,将root_device_name设置成sda1。

ROOT_DEV = name_to_dev_t(root_device_name);

在这之前,已经获取到了ROOT_DEV的描述符。

   1: if (initrd_load())

   2:     goto out;

   3:  

   4: /* wait for any asynchronous scanning to complete */

   5: if ((ROOT_DEV == 0) && root_wait) {

   6:     printk(KERN_INFO "Waiting for root device %s...\n",

   7:         saved_root_name);

   8:     while (driver_probe_done() != 0 ||

   9:         (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)

  10:         msleep(100);

  11:     async_synchronize_full();

  12: }

  13:  

  14: is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;

  15:  

  16: if (is_floppy && rd_doload && rd_load_disk(0))

  17:     ROOT_DEV = Root_RAM0;

  18:  

  19: mount_root();

  20:  

  21: devtmpfs_mount("dev");

  22: sys_mount(".", "/", NULL, MS_MOVE, NULL);

  23: sys_chroot((const char __user __force *)".");

如果initrd_load()成功了,就跳过mount_root这一步,这表明initrd_load()如果成功,就已经将root根文件系统给挂载好了。

否则,调用mount_root/mount_block_root,尝试以各种可能的文件系统挂载根文件系统

   1: static char * __initdata root_fs_names;

   2: static int __init fs_names_setup(char *str)

   3: {

   4:     root_fs_names = str;

   5:     return 1;

   6: }

   7:  

   8: static unsigned int __initdata root_delay;

   9:  

  10: __setup("rootfstype=", fs_names_setup);

   1: static int __init do_mount_root(char *name, char *fs, int flags, void *data)

   2: {

   3:     int err = sys_mount(name, "/root", fs, flags, data);

   4:     if (err)

   5:         return err;

   6:  

   7:     sys_chdir((const char __user __force *)"/root");

   8:     ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;

   9:     printk(KERN_INFO

  10:            "VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",

  11:            current->fs->pwd.mnt->mnt_sb->s_type->name,

  12:            current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?

  13:            " readonly" : "", MAJOR(ROOT_DEV), MINOR(ROOT_DEV));

  14:     return 0;

  15: }

因此,这里的错误在于,没有正确地执行initrd中的初始化程序,也没有成功地mount根文件系统。

明明是ext2的根文件系统,为什么没有被mount上呢?这是问题的根本原因。

分析无法进入Linux系统的原因的更多相关文章

  1. 玩转 Linux 系统的方法论

    Linus 说“Just for fun”,而我要说“Just for 折腾”.想知道我是怎样折腾 Linux 的,请看下面这个截图: 从这个截图可以看出,我为了“折腾” Linux 系统,在我的电脑 ...

  2. Linux江湖01:玩转Linux系统的方法论 (转载)

    http://www.blogjava.net/youxia/archive/2015/01/08/linux001.html 2014年上半年,我是在写RCP系列.然后,由于要准备研究生毕业论文和答 ...

  3. 1.部署虚拟环境安装linux系统

    第1章 部署虚拟环境安装linux系统 章节简述: 本章从零基础详细讲解了虚拟机软件与红帽Linux系统,完整演示了VM虚拟机的安装与配置过程,以及红帽RHEL 7系统的安装.配置过程和初始化方法.此 ...

  4. 【课程分享】深入浅出嵌入式linux系统移植开发 (环境搭建、uboot的移植、嵌入式内核的配置与编译)

    深入浅出嵌入式linux系统移植开发 (环境搭建.uboot的移植.嵌入式内核的配置与编译) 亲爱的网友,我这里有套课程想和大家分享,假设对这个课程有兴趣的,能够加我的QQ2059055336和我联系 ...

  5. 一次Linux系统被攻击的分析过程

    IT行业发展到现在,安全问题已经变得至关重要,从最近的“棱镜门”事件中,折射出了很多安全问题,信息安全问题已变得刻不容缓,而做为运维人员,就必须了解一些安全运维准则,同时,要保护自己所负责的业务,首先 ...

  6. linux系统 initrd.img中init启动脚本分析

    概述:这篇文章主体内容来源于网上转载.前面几篇文章倾向于制作initrd.img,这篇文章更倾向于initrd.img的运行过程:加载framebuff驱动 ide驱动和文件系统驱动,最后进入到真正的 ...

  7. LInux系统木马植入排查分析 及 应用漏洞修复配置(隐藏bannner版本等)

    在日常繁琐的运维工作中,对linux服务器进行安全检查是一个非常重要的环节.今天,分享一下如何检查linux系统是否遭受了入侵? 一.是否入侵检查 1)检查系统日志 检查系统错误登陆日志,统计IP重试 ...

  8. linux系统瓶颈分析(精)

    linux系统瓶颈分析(精) (2013-09-17 14:22:00)   分类: linux服务器瓶颈分析 1.0 性能监控介绍 性能优化就是找到系统处理中的瓶颈以及去除这些的过程,多数管理员相信 ...

  9. Linux系统故障分析与排查--日志分析

    处理Linux系统出现的各种故障时,故障的症状是最先发现的,而导致这以故障的原因才是最终排除故障的关键.熟悉Linux系统的日志管理,了解常见故障的分析与解决办法,将有助于管理员快速定位故障点,“对症 ...

随机推荐

  1. grub命令详解

    在grub下引导linux:其步骤如下;a 进入grub的命令模式.b 先熟悉一下grub 的一些命令 grub>help c 熟悉一下cat命令d root指令来指定/boot所在的分区e k ...

  2. 发送验证码倒计时60s

    var wait=60; function time(o) { if (wait == 0) { o.removeClass("gray"); o.text("发送验证码 ...

  3. HDU 1847 Good Luck in CET-4 Everybody! (巴什博弈)

    题目链接:HDU 1847 Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此. ...

  4. CS如何调用JS

    this.ClientScript.RegisterStartupScript(this.GetType(), "", "RunClick()", true); ...

  5. 第一周复习二 (CSS样式表及其属性)

    样式表三种写法 1内联写法:style直接写在标签内.个人感觉多用于个别标签,一般情况优先级较高 style="font-size:16px;" 2内嵌写法:写在<head& ...

  6. SQL Server 2014 中新建登录及权限分配【界面版】

    本篇经验将和大家介绍分配SQL Server 2014 中,新建登录用户,分配权限,并指定该用户的数据库的方法,希望对大家的工作和学习有所帮助! 方法/步骤 1 打开 MS SQL Server Ma ...

  7. 自定义DbUtils通用类

    本实例使用C3P0连接池做连接,详见https://www.cnblogs.com/qf123/p/10097662.html开源连接池C3P0的使用 DBUtils.java package com ...

  8. IDEA Caused by: java.lang.OutOfMemoryError: PermGen space

    错误:OutOfMemoryError: PermGen space 非堆溢出(永久保存区域溢出) 解决方法: 在Run/Debug configuration 的你要运行行的tomcat里面的 vm ...

  9. update 后没有加where条件解决办法

    MySQL 误操作后数据恢复(update,delete忘加where条件) 在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操 ...

  10. Codeforces 1149D 最短路 状压DP

    题意及思路:https://blog.csdn.net/yzyyylx/article/details/90145400 这题主要巧妙在分析了最短路算法的性质,得出大小小于等于3的连通块一定不会被再次 ...