根文件系统之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 ...
随机推荐
- hdu-1251(字典树)
字典树模板题. ps:数组要开大,40w左右才行,不然疯狂re 代码: #include<iostream> #include<algorithm> #include<c ...
- python optparser模块
python的内置模块中对于命令行的解析模块共两个getopt 和 optparse .不过getopt过于简单,往往不能满足需求.此时可以使用optparse模块.这个模块相对于getopt更新,功 ...
- Codeforces Round #446 Div. 1
B:即使看到n<=22也应该猜到这只是为了写spj.将每个数替换为恰好比他大的数即可,最大值替换为最小值.这样原序列中不包含最小值的集合显然都满足条件,并且容易发现包含最小值的集合的变化量都是最 ...
- 微信小程序——demo合集及简单的文档解读【五】
官方Demo https://github.com/wechat-miniprogram/miniprogram-demo 其他Demo https://www.cnblogs.com/ytkah/p ...
- MySQL 同一台服务器同步数据
声明:我配置出来的slave_io_running和slave_sql_running都是yes.但是数据并没有同步! 希望有遇到相同问题的朋友,能够告诉我一下解决方案? 首先,如何在同一个服务器安装 ...
- python学习日记(2/3区别,环境,变量,数据类型以及简单习题)
Python2 与 python3 的区别: python2源码不标准,混乱,重复代码太多 python3统一标准,去除重复代码 python2的默认编码方式是ASCII码,不能识别中文.解决方法:在 ...
- 登录Linux服务器显示IP和自定义备注
默认搭建好的Linux服务器,使用Xshell登录的窗口如下所示: 可根据需要执行如上代码,再重新登录服务器,效果如下图所示: 代码片段:echo "export PS1='\u@\[\e[ ...
- [NOI2012]美食节(费用流)
题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...
- CF1131E String Multiplication(???)
这题难度2200,应该值了. 题目链接:CF原网 题目大意:定义两个字符串 $s$ 和 $t$($s$ 的长度为 $m$)的乘积为 $t+s_1+t+s_2+\dots+t+s_m+t$.定义一个字符 ...
- linux(fedora) 第一课
1.Linux查看ip地址:ifconfig(interface config) 2.find / -name ifconfig (查找 从/开始找 找名字 匹配ifconfing) 复制命令:Ctr ...