上文: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. (2)C++基本类型

    一.整形 short .int. long. long long sizeof查看类型所占的字节数 cout << sizeof(short)<<endl;//2 字节 cou ...

  2. 9. Jmeter-前置处理器

    jmeter-前置处理器介绍与使用 JSR223 PreProcessor 用户参数 HTML链接解析器 HTTP URL 重写修饰符 JDBC PreProcessor RegEx User Par ...

  3. js全局变量优点和缺点

    全局变量的优点:可以减少变量的个数,减少由于实际参数和形式参数的数据传递带来的时间消耗. 全局变量的缺点: (1)全局变量保存在静态存贮区,程序开始运行时为其分配内存,程序结束释放该内存.与局部变量的 ...

  4. upc组队赛5 Bulbs

    Bulbs 题目描述 Greg has an m × n grid of Sweet Lightbulbs of Pure Coolness he would like to turn on. Ini ...

  5. 通过rocketmq思考一下mq的设计取舍

    1. RocketMQ路由中心NameServer 2. RocketMQ消息发送 3. RocketMQ消息存储 4. RocketMQ消息消费 5. 消息过滤FiterServer 6. Rock ...

  6. mysql中BLACKHOOL的作用

    MySQL在5.x系列提供了Blackhole引擎–"黑洞". 其作用正如其名字一样:任何写入到此引擎的数据均会被丢弃掉, 不做实际存储:Select语句的内容永远是空. 和Lin ...

  7. js转义符

    \0 :null(\u0000) \b :后退键(\u0008) \f :换页符(\u000C) \n :换行符(\u000A) \r :回车键(\u000D) \t :制表符(\u0009) \v ...

  8. stat - 打印信息节点(inode)内容

    SYNOPSIS(总览) stat filename [filenames ... ] DESCRIPTION(描述) stat 打印出一个信息节点的内容,它们显示为对人可读的格式的stat(2). ...

  9. ARM 汇编与C之间 的调用

    一. 汇编调用 C 1. 初始化栈 2. 初始化BSS段 (BSS 段是C语言存放未初始化的全局变量,或者初始化为0 的全局变量) 3 .使用 r0 ,r1, r2, r3 给函数传参,如果多于  4 ...

  10. Linux面试基础(一)

    Linux基本命令 man rm   查看命令帮助 tar cf 压缩文件 tar xf 解压缩 ping  查看是否能连接网络 rm           删除数据 find          搜索数 ...