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

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

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

  1. 使用BusyBox制作根文件系统的理论分析

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.inittab文件介绍 #first:run the system script file ::sysinit:/etc/init.d/ ...

  2. 嵌入式 详解制作根文件系统以及文件系统中init以及其他文件详解

    一.FHS(Filesystem Hierarchy Standard)标准介绍 当我们在linux下输入ls  / 的时候,见到的目录结构以及这些目录下的内容都大同小异,这是因为所有的linux发行 ...

  3. 嵌入式Linux利用busybox制作根文件系统

    本文介绍如何利用busybox制作一个最小根文件系统,系统包含ls.cd.ifconfig等基本指令,文件系统采用动态加载的方式. 1.去busybox官网下载源码   官网地址:busybox官网 ...

  4. 根文件系统制作一制作根文件系统树

    完成了u-boot移植后就是内核移植然后是根文件系统制作,这次分为这几部分书写:根文件系统树.文件系统initramfs.jaffs2.ubifs 有必要了解一些存储系统和文件系统的知识 Norfla ...

  5. 使用Buildroot为I.MX6制作根文件系统

    版本 作者 参与者 日期 备注 V1.0 wuya(微信号:wangwenxue1989) 2019/05/10 创建 1.引言 接触Freescale/NXP的I.MX6处理器大概有了两年的时间,对 ...

  6. [架构之路-30]:目标系统 - 系统软件 - Linux OS根文件系统rootfs的概念、组成、制作以及用busybox制作根文件系统

    目录 前言: 第1章 什么是根文件系统 1.1 什么是文件 1.2 什么是文件系统 1.3 文件系统组织文件的方式:树形结构 1.4 统一的虚拟文件系统 1.5 物理存储介质与物理文件系统类型 1.5 ...

  7. [ZedBoard移植嵌入式Linux教程(9,10)]编译设备树dts为dtb,制作根文件系统

    九.编译设备树dts为dtb 前面的linux内核源码目录中已经包含了设备树编译器Device Tree Compiler(dtc),在目录arch/arm/boot/dts/目录下. 将前面生成的x ...

  8. 基于Linux的Buildroot 制作根文件系统(rootfs)

    基于Linux的Buildroot 制作根文件系统(rootfs) 1.需要条件 2.安装交叉编译链 3.下载Buildroot代码包 4.开始buildroot 制作根文件系统 5.配置文件系统 m ...

  9. 制作根文件系统出现错误:No init found

    问题: 1.构建最小根文件系统时,出现错误: Warning: unable to open an initial console. Failed to execute /linuxrc. Attem ...

最新文章

  1. MySQL Proxy 安装与读写分离体验
  2. MC34063组成DC-DC电路
  3. 高等数学下-赵立军-北京大学出版社-题解-练习10.1
  4. 分布式事务Seata的AT模式下两阶段提交原理
  5. Nginx服务器学习(一)CentOS7系统安装Nginx
  6. 如何应对训练的神经网络不工作?
  7. 我们常用的软件测试工具有哪些?
  8. 好用家庭收支管理 1.0.20130204绿色免费版
  9. 网上打印个人完税证明流程
  10. linux nginx启动脚本,Nginx启动脚本大家来找茬
  11. 城市公交线路查询系统mysql_公交车路线查询系统后台数据库设计
  12. 图片如何高清修复?高清修复图片的方法
  13. 深入剖析ReentrantLock公平锁与非公平锁源码实现
  14. 手写字体的fisher算法识别
  15. 中学生用计算机的警句,中学生常用名言警句
  16. 字典型列表转化为csv文件格式
  17. DataDig 5.0.0::自动提取论文图表中曲线数据的软件
  18. 【LabVIEW】ELVIS III 、 myRIO 固件更新
  19. 2020年中国建筑信息模型(BIM)行业现状及竞争格局分析,未来将往6D方向发展「图」
  20. 【linux】centos7下使用和客户端远程链接sybase

热门文章

  1. Queue —— JUC 的豪华队列组件
  2. logisim无法打开解决办法
  3. informix和mysql的区别_DB2与Informix区别比较
  4. 输入法画面_仙剑奇侠传X百度输入法联名纪念版皮肤今日上线
  5. matlab绘制8条曲线,科学网—【Matlab】如何用plotyy对应坐标绘制多条曲线 - 叶瑞杰的博文...
  6. mysql 字段类型设计_Mysql字段类型设计相关问题!-阿里云开发者社区
  7. dom4j实现为list添加父节点_Heap 堆的实现
  8. 能利用计算机来模拟某种真实的实验现象,自然现象或社会现象的课件是,幼儿园课件制作教案...
  9. Sublime Text报错please wait a bit whilePyV8 binary is being downloaded
  10. 计算机项目开发流程,产品开发项目建议流程图怎样画