init进程的详解

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

参考博客

内核源码——C语言阶段的start_kernel函数_天糊土的博客-CSDN博客

分析根文件系统中的/linuxrc文件_天糊土的博客-CSDN博客

linux内核sys_mount()分析_kai_ding的博客-CSDN博客_sys_mount

【linux kernel】linux内核如何挂载根文件系统_iriczhao的博客-CSDN博客

一、前言提要

(1)start_kernel函数中的rest_init函数内容如下:

可知其调用kernel_thread函数启动了2个内核线程:kernel_init函数、kthreadd函数。

其中kernel_init函数内容如下,这个进程被称为init进程。

 

(2)注意,init进程和init程序(即linuxrc程序)是有区别的。

init进程一开始就有(是在rest_init函数中创建的),它运行于内核态,属于一个内核线程。后来init进程挂载根文件系统,并运行应用程序init程序后,init进程才从内核态进程转变为用户态进程。因为转变过程中进程号没有变,还是进程1,所以有人会把init程序(linuxrc程序)当做进程1。但其实init进程除了后面init程序的内容外,还包括内核态下挂载根文件系统等操作。

二、init进程从内核态向用户态的转变

1、一个进程先后两种状态

  • init进程刚开始运行的时候是内核态,它属于一个内核线程,然后运行一个用户态下面的程序后,把自己强行转成用户态(因为后面的进程需要工作在用户态下)。
  • init进程完成了从内核态到用户态的过渡,因此后续的其他进程都可以工作在用户态。

2、init进程在内核态下的工作内容

  • 主要是挂载根文件系统,并试图找到用户态下的那个init程序。(这句话看出,init进程是早于init程序运行的。)
  • init进程要把自己转成用户态就必须运行一个用户态的应用程序,要运行这个应用程序就必须得找到这个应用程序,要找到这个应用程序就必须得挂载根文件系统,因为所有的应用程序都在文件系统中。
  • 内核源代码中的所有函数都处于内核态,执行其中任何一个都不能脱离内核态。应用程序必须不属于内核源代码,这样才能保证应用程序处于用户态。这里执行的init程序和内核不在一起,由根文件系统另外提供。

3、init进程在用户态下的工作内容

  • init进程大部分有意义的工作都是在用户态下进行的。
  • init进程对操作系统的意义在于,其他所有的用户进程都直接或者间接派生自init进程

4、init进程如何从内核态跳跃到用户态

  • init进程处于内核态时,通过函数kernel_execve(见下文)来执行一个用户空间编译链接的应用程序就跳跃到用户态了。
  • 跳跃过程中进程号没有改变,一直是进程1。
  • 跳跃过程是单向的,一旦执行init程序转到用户态,整个操作系统就算真正运转起来了,以后只能在用户态下工作,用户态下想要进入内核态只能通过调用API。

三、init进程的工作内容

1、init进程打开了控制台

(1)linux系统中每个进程都有一个文件描述符表,表中存储的是本进程打开的文件。

(2)linux系统中一切皆是文件,因此设备也是以文件的方式来访问的。要访问一个设备,就要打开此设备对应的文件描述符。比如/dev/fb0这个设备文件就代表LCD显示器设备,/dev/buzzer代表蜂鸣器设备,/dev/console代表控制台设备。

(3)这里打开了/dev/console文件,并且复制了2次文件描述符,一共得到了3个文件描述符,分别是0、1、2,就是所谓的标准输入、标准输出、标准错误这3个文件描述符。

(4)进程1打开了这3个文件描述符,因此进程1衍生出来的所有的进程默认都具有这3个文件描述符。


2、init进程挂载了根文件系统

(1)prepare_namespace函数挂载根文件系统。

关于这个函数如何挂载根文件系统的,见博客linux内核如何挂载根文件系统 。

(2)uboot通过传参告知内核根文件系统的位置、根文件系统的文件系统类型等信息。 

  • 比如uboot传参中的“root=/dev/mmcblk0p2 rw”这一句就是告诉内核根文件系统在哪里。
  • 比如uboot传参中的“rootfstype=ext3”这一句就是告诉内核rootfs的类型。

(3)挂载结果(下面的描述是以inand启动为例,不是以tftp、NFS方式启动)

  • 如果内核挂载根文件系统成功,则会打印出:VFS: Mounted root (ext3 filesystem) on device 179:2。(也可能其他数字)
  • 如果挂载根文件系统失败,则会打印:No filesystem could mount root, tried:  yaffs2

(4)如果内核启动时挂载rootfs失败,则后面无法执行。

  • 内核中设置了启动失败后5s自动重启的机制,因此会看到反复重启的情况。

(5)如果挂载rootfs失败,可能的原因有

  • 最常见的错误就是uboot的bootargs设置不对。
  • rootfs烧录失败(fastboot烧录不容易出错)。
  • rootfs本身制作失败的。

3、init进程执行init程序(完成内核态到用户态的转变)

(1)执行prepare_namespace函数成功挂载rootfs后,接着执行init_post()函数。此函数进入rootfs中寻找应用程序的init程序,找到后调用run_init_process函数去执行。

(2)如何确定init程序是哪个文件?

  • 先判断uboot的传参cmdline中是否指定,如果指定则先执行cmdline中指定的程序。比如“init=/linuxrc”表示rootfs的根目录下的linuxrc程序就是init程序。下面代码就是执行/linuxrc的部分,其中变量execute_command的赋值过程见附录。它肯定是将cmdline解析后,从中得到 “init=/linuxrc” 这个项目。

  •  init=/linuxrc,这个/linuxrc一般是软连接,指向busybox,如下所示。

  • 如果uboot的传参cmdline中没有init=xx,或者cmdline中指定的这个xx执行失败,则执行备用方案:第一备用是/sbin/init,第二备用是/etc/init,第三备用是/bin/init,第四备用是/bin/sh。如果以上都不成功,则执行失败。

4、init进程构建了用户交互界面

(1)linux系统中一个进程的创建是通过其父进程创建出来的。根据这个理论只要有一个父进程就能生出一堆子孙进程了。

(2)init进程是其他用户进程的老祖宗。init启动了login进程(用户登录进程)、命令行进程(提供命令行环境)、shell进程(提供命令解释和执行)。

(3)shell进程启动了其他用户进程。命令行和shell一旦工作,用户就可以在命令行下通过./xx的方式来执行其他应用程序,每一个应用程序的运行就是一个进程。

四、附录

1、变量execute_command的赋值过程

在/init/main.c文件中有如下内容:

在/include/linux/init.h文件中,有如下定义:

/** Only for really core code.  See moduleparam.h for the normal way.** Force the alignment so the compiler doesn't space elements of the* obs_kernel_param "array" too far apart in .init.setup.*/
#define __setup_param(str, unique_id, fn, early)			\static const char __setup_str_##unique_id[] __initconst	\__aligned(1) = str; \static struct obs_kernel_param __setup_##unique_id	\__used __section(.init.setup)			\__attribute__((aligned((sizeof(long)))))	\= { __setup_str_##unique_id, fn, early }#define __setup(str, fn)	__setup_param(str, fn, fn, 0)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跟着石头哥哥学cocos2d-x(四)--cocos2dx中的动画以及TexturePacker使用

2019独角兽企业重金招聘Python工程师标准>>> 之前向Andreas Loew申请了一枚TexturePacker注册码,很快都下来了,作为回报我打算还是写一篇关于TexturePacker的使用博客吧,有兴趣的可以在这里申请密钥,http://www.codeandweb.com&am…

头像和Karma汽车

Powered by Zoundry RavenTechnorati : Karma, 头像, 汽车 Del.icio.us : Karma, 头像, 汽车 转载于:https://www.cnblogs.com/bsmagic/archive/2008/08/06/1261858.html

All-In-One Code Framework [一站式示例代码库] 【转】

All-In-One Code Framework [一站式示例代码库]2010 对一站式示例代码库,对奋战在一站式示例代码库上的每一位工程师来说都是不同寻常的一年。 在我们共同努力和开发社区的支持下,该项目从一年前的草根雏形,成长为CodePlex排名前三&#xff0…

Ioc容器Autofac介绍

Autofac是轻量级的开源Ioc容器,在这里可以下载http://code.google.com/p/autofac/。如果你用过其他的Ioc容器,那么学习Autofac使用也会比较容易,下面将通过一些例子来讲解其用法。 先看一个例子: 首先新建一个工程,添加…

用代码实现Sharepoint2010的个人信息的照片上传(2)(原创)

用代码从AD读取照片信息并同步到SharePoint2010的个人照片信息中 前言 上篇我们讲到用代码实现了照片信息同步到SharePoint2010的个人照片信息中,但是做的是从文件夹读取照片信息到SharePoint2010,今天我们要做的从AD的thumbnailPhoto属性中读取照片信息到SharePoin…

HTML5实现Word中文字全环绕图片效果

实现这个功能是当时看见数字报的展示出来的编排方式,就是图片热点,而且下载打开还是PDF的,让我这个WP用户咋个看。想实现Word中的编排方式,也需要浏览器支持Word插件,火狐、谷歌、Opera这些都要另外弄插件,…

Bzoj 2127 happiness 最小割

happiness 题解: 将图转换成最小割. 将割完的图中与S相连的点看做选文科, 与T相连的点看做选理科. flow(s, u) 文科值 flow(u,t) 理科值 假设u 和 v 一起选文科有奖励值z, flow(s,u) z/2 flow(s,v) z/2, flow(u,v) z/2 假设u 和 v 一起选理科有奖励值z, flow(u,t) z/2…

POJ 1149 最大流建图 PIGS

题意: 给出猪圈个数 m 和买家人数 n 然后给出m个猪圈的猪的头数.. 接下来 n 行.. 给出mm a1 a2 .. a(mm) k 例如 2 1 5 3 表示第i1个用户 有mm(2) 个猪圈的钥匙 就是有第 a1(1) 个和第 a2(5) 个猪圈的钥匙..还想要买得k头猪.. 问最多能够卖出多少头.. 思路&#xff…

ARM通识——ARM的7种基本工作模式、37个通用寄存器

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 一、ARM采用32位架构 ARM约定一个Byte是8 bits,一个Halfword是16 bits (2 byte),一个Word是32 bits (4 byte)。 大部分ARM core 提供ARM 指令集(32 bit&#xff0…

以NFS方式挂载rootfs的设置方法

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 更多详细内容,见Linux中NFS服务器的配置(/etc/export)_天糊土的博客-CSDN博客 网络文件系统(NFS,network file system),是一种网络通讯协…

分析根文件系统中的/linuxrc文件(附带busybox的介绍)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 参考博客 init进程的详解_天糊土的博客-CSDN博客_init进程 busybox详解_linuxarmsummary的博客-CSDN博客 前言 因为uboot给内核传参的bootargs中有“init/linuxrc”这个项目,而由前面的…

CentOS Linux搭建SVN Server配置详解

PS:今天给开发的同事搭建一个公网的SVN Server,google一下,发现下面这篇最详细,就记录下来,重新排版一下。顺便根据自己的使用经验,补充了几个细节和总结。本文配置是基于CentOS 5.x的,但一样适…

405 Method Not Allowed

当jquery easyui的datagrid插件使用.json文件为数据源,通过非http协议访问【就是直接拖进浏览器查看效果】,能正常加载.json文件并且生成datagrid数据源。但是通过http协议访问示例代码时,无法加载json文件生成datagrid的数据源。 这个是由于…

Eclipse之ANT使用

Ant是Java平台下非常棒的批处理命令执行程序,能非常方便地自动完成编译,测试,打包,部署等等一系列任务,大大提高开发效率。如果你现在还没有开始使用Ant,那就要赶快开始学习使用,使自己的开发水…

idea修改maven项目版本号

1 先安装插件 2 控制台执行命令 mvn build-helper:parse-version versions:set -DnewVersion1.1-SNAPSHOT versions:commit 1.1-SNAPSHOT 为你要修改的版本号 技术交流群: 816227112 有时候命令执行完看不到改变,需要刷新下。 转载于:https://www.cnblo…

几个国外开源CMS系统比较

CMS是Content Management System的缩写,意为"内容管理系统"。上一下度娘或者放一下Google,全球的CMS系统,不下千个,开源的不下百个,如果只是普通用户,很难有时间和精力去比较那么多的系统优劣。不…

javascript函数,值得参考!

2019独角兽企业重金招聘Python工程师标准>>> javascript函数一共可分为五类:   常规函数   数组函数   日期函数   数学函数   字符串函数   1.常规函数   javascript常规函数包括以下9个函数:   (1)alert函数:显…

时钟系统——S5PV210的时钟系统的理论及操作

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。 参考内容 s5pv210——初始化时钟 - biaohc - 博客园 用户手册 一、SoC时钟系统 1、时钟的含义与作用 时钟是同步工作系统的同步节拍。 SoC内部有很多器件,比如CPU、串口、DRAM控制器、…

Oracle 协议适配器错误

1.首先确认你的 OracleDBConsoleORACLE,OracleOraDb11g_home1TNSListener,OracleServiceORACLE 这三个服务是否已经正常的开启。 2. 确认你的listener 的端口是否被占用, 在命令行执行:netstat -aon|findstr "1521" &am…

串口通信——串口通信的基础概念

以下内容源于朱友鹏嵌入式课程的学习与整理,如有侵权请告知删除。 参考博客 同步通信与异步通信区别_wind19的博客-CSDN博客 SPI、I2C、UART(即串口)三种串行总线详解_天糊土的博客-CSDN博客_串口总线 一、电子通信相关的概念 1、同步通信和…