根文件系统之init
title: 根文件系统之init
tag: arm
date: 2018-11-12 18:53:23
引入
在Kernel源码分析中,了解到init_post
是在挂载根文件系统之后执行应用程序
打开标准输入/输出/错误
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 < MAX_INIT_ARGS; i++)
argv_init[i] = NULL;
return 1;
}
__setup("init=", init_setup);
也是设置一个段属性固定的结构体
#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
根文件系统之init的更多相关文章
- 构建根文件系统之init进程分析
busybox是ls.cp等命令的集合. 执行ls时,实际上是执行了busybox ls 执行cp时,实际上是执行了busybox cp 分析init程序之前,再让我们回想一下我们的目标:u-boot ...
- 第4阶段——制作根文件系统之编译配置安装busybox(3)
在上一节分析出制作一个最小的根文件系统至少需要: (1)/dev/console(终端控制台, 提供标准输入.标准输出以及标准错误) /dev/null (为空的话就是/dev/null, 所有写到 ...
- Qemu搭建ARM vexpress开发环境(三)----NFS网络根文件系统
Qemu搭建ARM vexpress开发环境(三)----NFS网络根文件系统 标签(空格分隔): Qemu ARM Linux 经过上一篇<Qemu搭建ARM vexpress开发环境(二)- ...
- 第4阶段——制作根文件系统之分析init进程(2)
本节目标: (1) 了解busybox(init进程和命令都放在busybox中) (2) 创建SI工程,分析busybox源码来知道init进程做了哪些事情 (3) 分析busybox中init进 ...
- 制作根文件系统之Busybox init进程的启动过程分析
先来介绍一下什么是Busybox:它是将众多的UNIX命令集合进一个很小的可执行程序中. 在制作根文件系统之内核如何启动init进程中遗留了一个问题是/linuxrc是内核启动的第一个应用程序,那么它 ...
- 制作根文件系统之内核如何启动init进程
start_kernel其实也是内核的一个进程,它占用了进程号0,start_kernel的内容简写如下: asmlinkage void __init start_kernel(void) //内核 ...
- Linux之搭建自己的根文件系统
Hi!大家好,我是CrazyCatJack.又和大家见面了.今天给大家带来的是构建Linux下的根文件系统.希望大家看过之后都能构建出符合自己需求的根文件系统^_^ 1.内容概述 1.构造过程 今天给 ...
- Linux学习 :Uboot, Kernel, 根文件系统初步分析
1.U-Boot启动内核的过程可以分为两个阶段: 1)第一阶段的功能 硬件设备初始化 加载U-Boot第二阶段代码到RAM空间 设置好栈 跳转到第二阶段代码入口 2)第二阶段的功能 初始化本阶段使用的 ...
- linux根文件系统制作
在嵌入式中移植的内核下载到开发板上,是没有办法真正的启动Linux操作系统的,会出现无法加载文件系统的错误. 那么根文件系统在系统启动中到底是什么时候挂载的呢?先将/dev/ram0挂载,而后执行/l ...
随机推荐
- Nginx 如何减轻高流量下的压力
L:102 比如 Nginx 缓存服务出现问题(比如新增服务器等造成缓存失效) 所有资源请求直接穿透上游服务器 造成上游服务器压力倍增 特别热点文件 都是访问同个文件 以下可以减轻上述问题 第二种方 ...
- .resx文件与.cs文件的自动匹配
图中myCommands.Resx是<DependentUpon> myCommands.cs文件的. 如何为其他的.cs文件添加类似的资源文件呢? 其实挺简单, 添加与.cs文件同名的资 ...
- Idea中JavaWeb项目部署
1. 添加应用服务器tomcat 2. 将tomcat配置添加到项目中 artifacts配置:添加deploy, 添加artifacts,选择Web Application: Exploded &g ...
- PXE网络装机
PXE网络装机配置 安装CentOS 6.5系统 1.配置服务端IP地址和yum源 略 2.安装配置VSFTP服务 vsftpd 的作用:为客户端提供FTP服务,便于客户端下载操作系统 (1)安装vs ...
- 基准对象object中的基础类型----数字 (二)
object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...
- 复习 LIS nlogn
参考:https://www.cnblogs.com/wxjor/p/5524447.html 最长下降只要把符号都倒过来就行 在栈中二分找第一个比当前值小的替换就行
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- 一种HBase表数据迁移方法的优化
1.背景调研: 目前存在的hbase数据迁移主要分如下几类: 根据上图,可以看出: 其实主要分为两种方式:(1)hadoop层:因为hbase底层是基于hdfs存储的,所以可以通过把hdfs上的数据拷 ...
- 【AGC002E】Candy Piles 博弈论
题目大意 有\(n\)堆糖果,第\(i\)堆有\(a_i\)个. 两个人轮流决策,决策分为两种: 1.选择糖果数最多的一堆糖果,并把这堆糖全吃了. 2.在每堆非空的糖果堆里拿一颗糖吃掉. 吃掉最后一颗 ...
- 修改KVM的模拟网卡类型
修改KVM的模拟网卡类型 来源 https://www.cnblogs.com/EasonJim/p/9751051.html 在KVM下可以生成两种型号的网卡,RTL8139和E1000,其实应该是 ...