热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

根文件系统之init

title:根文件系统之inittag:armdate:2018-11-1218:53:23---引入在Kernel源码分析中,了解到init_post是在挂载根文件系统之后

title: 根文件系统之init
tag: arm
date: 2018-11-12 18:53:23
---

引入

在Kernel源码分析中,了解到init_post是在挂载根文件系统之后执行应用程序

mark

mark

打开标准输入/输出/错误

Linux首先打开标准输入scanf,标准输出printf,标准错误err


if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) <0)
    printk(KERN_WARNING "Warning: unable to open an initial console.\n");

(void) sys_dup(0);  //这个是复制的意思
(void) sys_dup(0);

这里的sys_dup(0)表示复制打开的第0个文件,也就是/dev/console,也就是说准输入scanf,标准输出printf,标准错误err都定位到/dev/console这个文件,这个文件被称为终端,他可以是串口或者液晶键盘组合等

执行init进程

接下来会处理U-boot传递进来的命令行参数

//run_init_process 一般会正确执行不会返回的程序
if (execute_command) {
    run_init_process(execute_command);
    printk(KERN_WARNING "Failed to execute %s.  Attempting "
           "defaults...\n", execute_command);
}

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found.  Try passing init= option to kernel.");

我们搜索下execute_command,发现如下定义,很明显和kernel源码分析中的命令行参数类似

static int __init init_setup(char *str)
{
    unsigned int i;

    execute_command = str;
    /*
     * In case LILO is going to boot us with default command line,
     * it prepends "auto" before the whole cmdline which makes
     * the shell think it should execute a script with such name.
     * So we ignore all arguments entered _before_ init=... [MJ]
     */
    for (i = 1; i #define __setup(str, fn)                    \
    __setup_param(str, fn, fn, 0)

#define __setup_param(str, unique_id, fn, early)            \
    static char __setup_str_##unique_id[] __initdata = str; \
    static struct obs_kernel_param __setup_##unique_id  \
        __attribute_used__              \
        __attribute__((__section__(".init.setup"))) \
        __attribute__((aligned((sizeof(long)))))    \
        = { __setup_str_##unique_id, fn, early }

也就是构造了一个和root=/dev/mtdblock3类似的

static char __setup_str_init_dev_setup[] __initdata = "init=";
static struct obs_kernel_param __setup_init_dev_setup 
    __attribute_used__
    __attribute__((__section__(".init.setup"))) 
    __attribute__((aligned((sizeof(long)))))    
    ={
        __setup_str_init_dev_setup,root_init_setup,init_dev_setup,0
    }
    
这个结构体的原型如下
struct obs_kernel_param 
{
    const char *str;
    int (*setup_func)(char *);
    int early;
};

也就是说execute_command=/linuxrc,因为u-boot传递的参数是init=/linuxrc,程序会使用run_init_process(execute_command);来处理这个命令行

注意 函数run_init_process一般会正确执行不会返回的程序,也就是说如果能够正确执行u-boot传递的参数,将不会执行以下

run_init_process("/sbin/init"); //如果命令行参数不正确才会执行这个应用程序
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found.  Try passing init= option to kernel.");

小结测试

(一)

烧录u-boot,烧录Linux,擦除根文件系统nand erase root,也就是不放根文件系统,系统会有如下提示

VFS: Mounted root (yaffs filesystem).       
挂接了根文件系统,但是flash是空的,默认识别为yaffs
Freeing init memory: 140K
Warning: unable to open an initial console.
flash是空的,无法启动应用程序
Failed to execute /linuxrc.  Attempting defaults...
错误指示--命令行
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.

因为格式化了flash,系统可以识别为任意的文件系统,默认识别为yaffs,但是由于没有根文件系统,所以无法打开标准输入输出,按照代码所写的提示错误

printk(KERN_WARNING "Warning: unable to open an initial console.\n");

同时也就无法打开init进程,提示

panic("No init found.  Try passing init= option to kernel.");

(二)

烧入根文件系统,在u-boot下输入y,下载文件系统fs_mini.yaffs2,然后启动.输入ps看下启动的应用程序

# ps
  PID  Uid        VSZ Stat Command
    1 0          3092 S   init
    2 0               SW<[kthreadd]
    3 0               SWN [ksoftirqd/0]
    4 0               SW<[watchdog/0]
    5 0               SW<[events/0]
    6 0               SW<[khelper]
   55 0               SW<[kblockd/0]
   56 0               SW<[ksuspend_usbd]
   59 0               SW<[khubd]
   61 0               SW<[kseriod]
   73 0               SW  [pdflush]
   74 0               SW  [pdflush]
   75 0               SW<[kswapd0]
   76 0               SW<[aio/0]
  710 0               SW<[mtdblockd]
  745 0               SW<[kmmcd]
  767 0          3096 S   -sh
  769 0          3096 R   ps

这里init就是启动的第一个进程sh也就是终端接收输入以及打印的输出

init实现

在嵌入式Linux中的一些基础命令例如ls,cp等实际上也是一个个App,这些基本命令一般由busybox编译得到一个名为busybox的应用程序.然后ls,cd,cp等命令一般是其链接.可以使用ls-l xxx来查看其链接属性.可以先用which xxx查看其位置,然后看属性

# ls -l /bin/ls
lrwxrwxrwx    1 1000     1000            7 Jan  6  2010 /bin/ls -> busybox

# ls
bin         lib         mnt         sbin        usr
dev         linuxrc     proc        sys
etc         lost+found  root        tmp

# busybox ls
bin         lib         mnt         sbin        usr
dev         linuxrc     proc        sys
etc         lost+found  root        tmp

其实,/sbin/init也是到busybox的链接

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");


# which init
/sbin/init
# ls -l /sbin/init
lrwxrwxrwx    1 1000     1000           14 Jan  6  2010 /sbin/init -> ../bin/busybox

推荐阅读
  • 掌握DSP必备的56个核心问题,我已经将其收藏以备不时之需! ... [详细]
  • 欢迎来到Netgen新时代:探索网络生成技术的无限可能
    欢迎进入Netgen的新时代:探索网络生成技术的无限潜力。本文将详细介绍如何编译下载的Netgen源代码,生成Netgen程序,并提供开发所需的库nglib。此外,还将探讨Netgen在现代网络设计与仿真中的应用前景,以及其在提高网络性能和可靠性方面的关键作用。 ... [详细]
  • 在 Linux 系统中,`/proc` 目录实现了一种特殊的文件系统,称为 proc 文件系统。与传统的文件系统不同,proc 文件系统主要用于提供内核和进程信息的动态视图,通过文件和目录的形式呈现。这些信息包括系统状态、进程细节以及各种内核参数,为系统管理员和开发者提供了强大的诊断和调试工具。此外,proc 文件系统还支持实时读取和修改某些内核参数,增强了系统的灵活性和可配置性。 ... [详细]
  • SpringBoot启动脚本详解:BAT文件应用与基础入门指南(SpringBoot系列第1篇)
    如果你还在为SSM框架的复杂搭建过程和繁琐的配置文件而烦恼,那么SpringBoot将是你的一大福音。作为SpringBoot系列的第一篇文章,本文详细介绍了如何使用BAT文件来启动SpringBoot应用,并提供了基础入门指南,帮助开发者快速上手,简化开发流程。 ... [详细]
  • 本文详细介绍了使用响应文件在静默模式下安装和配置Oracle 11g的方法。硬件要求包括:内存至少1GB,具体可通过命令`grep -i memtotal /proc/meminfo`进行检查。此外,还提供了详细的步骤和注意事项,确保安装过程顺利进行。 ... [详细]
  • Python学习:环境配置与安装指南
    Python作为一种跨平台的编程语言,适用于Windows、Linux和macOS等多种操作系统。为了确保本地已成功安装Python,用户可以通过终端或命令行界面输入`python`或`python3`命令进行验证。此外,建议使用虚拟环境管理工具如`venv`或`conda`,以便更好地隔离不同项目依赖,提高开发效率。 ... [详细]
  • 在《孙鑫VC++讲座笔记第三讲》中,深入探讨了MFC应用程序的架构,并详细解析了SDI程序的流程图。AfxWinMain()函数位于WINMAIN.CPP文件中,其主要职责包括调用AfxWinInit()进行框架初始化,以及通过pApp->InitApplication()执行应用内部的初始化过程。此外,还详细分析了各个关键函数的作用及其在程序启动过程中的具体功能。 ... [详细]
  • 在Linux环境下编译安装Heartbeat时,常遇到依赖库缺失的问题。为确保顺利安装,建议预先通过yum安装必要的开发库,如glib2-devel、libtool-ltdl-devel、net-snmp-devel、bzip2-devel和ncurses-devel等。这些库是编译过程中不可或缺的组件,能够有效避免编译错误,确保Heartbeat的稳定运行。 ... [详细]
  • Python网络爬虫入门:利用urllib库进行数据抓取
    Python网络爬虫入门:利用urllib库进行数据抓取在数据科学和Web开发领域,Python凭借其简洁高效的特性成为首选语言。本文主要介绍了如何在Windows环境下使用Python的urllib库进行基本的网络数据抓取。考虑到命令行操作的不便,作者选择了Jupyter Notebook作为开发环境,不仅简化了配置过程,还提供了直观的数据处理和可视化功能。通过实例演示,读者可以轻松掌握urllib的基本用法,为深入学习网络爬虫技术打下坚实基础。 ... [详细]
  • 题目《UVa 11978 福岛核爆问题》涉及圆与多边形交集面积的计算及二分法的应用。该问题的核心在于通过精确的几何运算与高效的算法实现来解决复杂图形的面积计算。在实现过程中,特别需要注意的是对多边形顶点的平移处理,确保所有顶点包括最后一个顶点 \( p[n] \) 都经过正确的位移,以避免因细节疏忽导致的错误。此外,使用循环次数为50次的二分法能够有效提高算法的精度和稳定性。 ... [详细]
  • 如何利用Apache与Nginx高效实现动静态内容分离
    如何利用Apache与Nginx高效实现动静态内容分离 ... [详细]
  • 在Python 2.7环境中使用PyCharm进行Cvxopt的安装及线性规划问题求解。具体步骤包括:通过PyCharm的文件菜单进入项目设置,选择解释器选项,点击右侧的“+”按钮,在可用包列表中搜索并安装Cvxopt。安装完成后,可以通过导入Cvxopt库并调用其函数来解决线性规划问题,提高模型的准确性和效率。 ... [详细]
  • 本文详细介绍了在 Sublime Text 中配置 Lua 编译环境的方法与实际操作步骤。首先,用户需获取 `lua.exe` 和 `luac.exe`,可通过安装 Lua for Windows 或 SciTE 实现,也可自行编译源代码。接着,将 `lua.exe` 的路径(如 C:\Program Files\Lua\)添加至系统环境变量中,确保命令行可全局调用。此外,文中还提供了配置 Sublime Text 构建系统的具体设置,帮助开发者高效调试 Lua 脚本。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • 第五章详细探讨了 Red Hat Enterprise Linux 6 中的 Ext3 文件系统。5.1 节介绍了如何创建 Ext3 文件系统,包括必要的命令和步骤,以及在实际操作中可能遇到的问题和解决方案。此外,还涵盖了 Ext3 文件系统的性能优化和维护技巧,为用户提供全面的操作指南。 ... [详细]
author-avatar
破背包
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有