第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)

 

本章学习如何启动第一个应用程序

1.在前面的分析中我们了解到,在init进程中内核挂接到根文件系统之后,会开始启动第一个应用程序:

kernel_init函数代码如下:

static int __init kernel_init(void * unused)    //进入init进程                                  
{    prepare_namespace()  //挂载根文件系统{... ...      / /通过解析出来的命令行参数” root=/dev/mtdblock3”来挂接根文件系统 mount_root();   //开始挂载}init_post();           //启动应用程序     
}
}

2.接下来开始分析init_post()如何启动应用程序的,代码如下:

static int noinline init_post(void)
{/*内核已经初始化完成,所以清除__init_begin段到__init_end段之间的数据*/free_initmem();unlock_kernel();mark_rodata_ro();system_state = SYSTEM_RUNNING;numa_default_policy(); /*  打开dev/console控制台设备(串口0),使用户能输入信息, /dev/console即成为kernel_init进程的标准输入源(文件描述符0),
打开失败则打印Warning: unable to open an initial console.\n
*/if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)printk(KERN_WARNING "Warning: unable to open an initial console.\n");

当我们删除根文件系统的内容再启动内核,发现串口就会打印上面的字符串,如下图:

会显示打开dev/console失败,是因为根文件系统还是在root=/dev/mtdblock3, 所以能挂载根文件系统,我们擦除了mtd3内容,也就是dev里面的内容,所以无法打开console控制台。 

接下来继续分析init_post():

/*调用dup打开/dev/console文件描述符两次, 该控制台设备就也可以供标准输出和标准错误使用(文件描述符1和2),
kernel_init进程现在就拥有3个文件描述符--标准输入、标准输出以及标准错误。
*/(void) sys_dup(0);(void) sys_dup(0);
if (ramdisk_execute_command) { //若 ramdisk_execute_command为0,不运行它run_init_process(ramdisk_execute_command); printk(KERN_WARNING "Failed to execute %s\n",ramdisk_execute_command); }

搜索上面ramdisk_execute_command,发现它是一个char型全局数组,找到它被用在init_setup()中,代码如下:

static int __init rdinit_setup(char *str)
{unsigned int i;/* 使ramdisk_execute_command数组等于str  *、ramdisk_execute_command = str;     /* See "auto" comment in init_setup */for (i = 1; i < MAX_INIT_ARGS; i++)argv_init[i] = NULL;return 1;
}__setup("rdinit=", rdinit_setup);
ramdisk_execute_command

发现上面__setup和我们上节分析的挂载根文件系统的__setup都是一样的

它是匹配命令行中以” rdinit=”开头的字符串,由于我们uboot的命令行参数中没有”rdint=”,所以ramdisk_execute_command=0,不执行if判断

接下来继续分析init_post():

if (execute_command) {   // execute_command不为0, 运行它/* run_init_process 运行目标程序成功后会一直死循环*/          
run_init_process(execute_command);  /*run_init_process运行失败退出后,打印Failed to execute /linuxrc.  Attempting defaults...  */printk(KERN_WARNING "Failed to execute %s.  Attempting ""defaults...\n", execute_command);}

搜索上面execute_command,发现它是一个char型全局数组,找到它被用在init_setup()中,代码如下:

static int __init init_setup(char *str)
{unsigned int i;/*execute_command =str*/execute_command = str;     for (i = 1; i < MAX_INIT_ARGS; i++)argv_init[i] = NULL;return 1;
}
__setup("init=", init_setup);
execute_command

发现上面__setup和我们上节分析的挂载根文件系统的__setup都是一样的

显然这里就是用来匹配命令行中以” init=”开头的字符串,然后再将命令行参数bootargs中的” init=/linuxrc”中的” /linuxrc”放在execute_command数组中.

(init=/linuxrc:指定内核启动后运行的第一个脚本是当前目录下linuxrc脚本)     

最终__setup("init=", init_setup)宏= { __setup_str_ root_dev_setup[], root_dev_setup , 0 };

然后放在.init.setup段中,在内核启动后进入start_kernel()函数中使用这个宏,并将” /linuxrc”放在execute_command数组中.

当文件系统被擦除后,就会运行linuxrc应用程序失败,打印执行linuxrc失败,如下图:

 

接下来继续分析init_post():

/*运行应用程序失败后,从下面3个地方查找可能出现 init应用程序的所有地方*/run_init_process("/sbin/init");run_init_process("/etc/init");run_init_process("/bin/init");/*试图建立/bin/sh 来代替应用程序 */run_init_process("/bin/sh");/*如上图所示,当前面的所有情况都失败时,调用panic。这样内核就会试图同步磁盘,确保其状态一致。
如果超过了内核选项中定义的时间,它也可能会重新启动机器。
*/panic("No init found. Try passing init= option to kernel.");}

在这里init_post函数就分析完毕了.

3.当在内核中,能输入数据时,表示根文件系统的应用程序启动完毕

比如输入ps查看进程,如下图,(ps-process status)

 

接下来开始分析init进程,知道命令是怎么来的

转载于:https://www.cnblogs.com/lifexy/p/7405838.html

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

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

相关文章

Golang并发——并发技术Goroutine和channel的使用、定时器、生产者消费者、条件变量、select

Goroutine: goroutine是Go并行设计的核心。goroutine说到底其实就是协程&#xff0c;它比线程更小&#xff0c;十几个goroutine可能体现在底层就是五六个线程&#xff0c;Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB)&#x…

Oozie协作框架

Oozie协作框架 一&#xff1a;概述 1.大数据协作框架 2.Hadoop的任务调度 3.Oozie的三大功能 Oozie Workflow jobs Oozie Coordinator jobs Oozie Bundle 4.Oozie的架构 控制流节点 起始&#xff0c;分支&#xff0c;并发&#xff0c;汇合&#xff0c;结束 动作节点action 5.O…

11.4 专利法与反不正当竞争法解读

第六条是对于职务作品的一个定性.它这个职务作品、职务发明创造和我们前面著作法所讲到的职务作品的处理方式基本一致.就是如果认定某一个作品它是属于职务作品、职务发明创造,那么这一个作品它的专利权应该是属于单位而不是个人.只有认定这个创造为非职务发明创造的时候,申请的…

一文入门网络编程:常见协议、通信过程、Socket、CS/BS、TCP/UDP

网络编程三要素&#xff1a;ip地址、端口、协议&#xff0c;在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;可以进行数据传输 常见协议&#xff1a; 传输层 常见协议有TCP/UDP协议。应用层 常见的协议有HTTP协议&#xff0c;FTP协议。网络层 常见协议有IP协议…

【Linux笔记(000) 】-- 系统启动过程

索引&#xff1a; 目录索引 一. 启动流程 BIOS --> MBR(Boot Code) --> 引导程序(GRUB) --> 加载内核 --> 执行Init --> runlevel 二. 内容详解 BIOS: Basic Input Output System , 基本输入输出系统 ,负责检查硬件,查找启动设备, 可启动设备在BIOS中定义。…

Golang——TCP、UDP实现并发(服务端与客户端)

Server端常用函数、接口&#xff1a; Listen函数&#xff1a;func Listen(network, address string) (Listener, error)network&#xff1a;选用的协议&#xff1a;TCP、UDP&#xff0c; 如&#xff1a;“tcp”或 “udp”address&#xff1a;IP地址端口号, 如&#xff1a;…

java中 将字符串时间 '2015-9-8 17:05:06' 转化为格式 '2015-09-08 17:05:06'

/** * 将字符串时间2015-9-8 17:05:06转化为格式2015-09-08 17:05:06 */import java.text.SimpleDateFormat; public class TestDate{ public static void main(String[] args) throws Exception{ String time "2015-9-8 17:05:06";//注意&#xff1a;时分秒必须都…

详解TCP协议三次握手四次挥手

三次握手&#xff1a; 三次握手表示建立通信阶段&#xff0c;在TCP协议中&#xff0c;在发送数据的准备阶段&#xff0c;客户端与服务器之间的三次交互&#xff0c;以保证连接的可靠&#xff0c;由于这种面向连接的特性&#xff0c; TCP协议可以保证传输数据的安全&#xff0c;…

Golang——实现文件传输

借助TCP完成文件的传输&#xff0c;基本思路如下&#xff1a; 发送方&#xff08;客户端&#xff09;向服务端发送文件名&#xff0c;服务端保存该文件名。接收方&#xff08;服务端&#xff09;向客户端返回一个消息ok&#xff0c;确认文件名保存成功。发送方&#xff08;客户…

Golang——HTTP编程请求和响应实现

请求&#xff1a; HTTP 请求报文由请求行、请求头部、空行、请求包体4个部分组成&#xff0c;如下图所示&#xff1a; 请求行&#xff1a; 请求行由方法字段、URL 字段 和HTTP 协议版本字段 3个部分组成&#xff0c;他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST。…

zabbix v3.0安装部署【转】

关于zabbix及相关服务软件版本&#xff1a; Linux&#xff1a;oracle linux 6.5 nginx&#xff1a;1.9.15 MySQL&#xff1a;5.5.49 PHP&#xff1a;5.5.35 一、安装nginx&#xff1a; 安装依赖包&#xff1a; yum -y install gcc gcc-c autoconf automake zlib zlib-devel ope…

WeChatTweak-微信小助手安装教程

github下载&#xff1a;https://github.com/Sunnyyoung/WeChatTweak-macOS CSDN下载&#xff1a;https://download.csdn.net/download/weixin_45477086/83895866 双击解压下载的WeChatTweak-macOS-***.zip在终端输入cd ,并敲一个空格&#xff0c;然后把解压的文件夹拖到终端 …

nodejs开发工具

我选择的是Hbuilder作为node项目的开发工具。先在Hbuilder 里面安装nodeEclipse插件&#xff0c;然后重启工具。点击添加项目&#xff0c;选择其他选项&#xff0c;出现下图选项&#xff0c;然后选择圈住的选项点击下一步:3. 如果不使用缺省位置&#xff0c;那么你的路径一定要…

排序之外部排序

有时&#xff0c;待排序的文件很大&#xff0c;计算机内存不能容纳整个文件&#xff0c;这时候对文件就不能使用内部排序了&#xff08;这里做一下说明&#xff0c;其实所有的排序都是在内存中做的&#xff0c;这里说的内部排序是指待排序的内容在内存中就可以完成&#xff0c;…

Golang——Json的序列化和反序列化

JSON&#xff1a; JSON(JavaScript Object Notation)&#xff1a;是一种轻量级的数据交换格式。 它是基于 ECMAScript 规范的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写…

安装配置 flannel - 每天5分钟玩转 Docker 容器技术(59)

上一节我们部署了 etcd&#xff0c;本节安装和配置 flannel。 build flannel flannel 没有现成的执行文件可用&#xff0c;必须自己 build&#xff0c;最可靠的方法是在 Docker 容器中 build。不过用于做 build 的 docker 镜像托管在 gcr.io&#xff0c;国内可能无法直接访问&a…

人人都是产品经理?

产品经理顾名思义就是产品经理。那么只要搞懂产品是什么、经理又什么什么&#xff0c;就明白了产品经理是什么。 产品是什么&#xff1a; 产品是满足需求的载体&#xff0c;能被市场、人们使用和消费&#xff0c;并能满足人们某种需求&#xff08;创造价值&#xff09;的任何东…

搭建一个简单的FTP服务器

本文介绍通过win7自带的IIS来搭建一个只能实现基本功能的FTP服务器&#xff0c;第一次装好WIN7后我愣是没整出来&#xff0c;后来查了一下网上资料经过试验后搭建成功&#xff0c;其实原理和步骤与windows前期的版本差不多&#xff0c;主要是对新的操作系统还不是很熟悉。相信用…

3D文档(BRD、MRD、PRD)怎么写

3D文档&#xff1a; 一般来说&#xff0c;BRD作为战略方向的制定&#xff0c;是最早产出的文档&#xff0c;而MRD则是在战略方向的基础上对市场进行的分析&#xff0c;同时对后续工作的方向进行一些说明和指导&#xff0c;也可以说是通过对市场环境、竞品的分析&#xff0c;明确…

需求收集、分析、管理的方法

需求&#xff1a; 什么是需求 百度百科给的解释&#xff1a;指人们在某一特定的时期内在各种可能的价格下愿意并且能够购买某个具体商品的需要。所以要想明白需求&#xff0c;还要明白另外两个概念&#xff0c;需要和欲望&#xff0c;因为从需要到需求是一个由宏观到微观的过程…