farsight 构建Linux根文件系统

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

构建Linux根文件系统

1. 根文件系统

1.1 定义

存放系统启动所必需的文件

内核映像文件(嵌入式系统中,内核一般单独存放在一个分区中);

内核启动后运行的第一个程序(init);

shell程序;

应用程序所依赖的库;

…...

1.2 目录结构

1.2.1 FHS标准:

(Filesystem Hierarchy Standard,文件系统层次标准);

定义文件系统中目录、文件存放的原则,不是强制性标准。

1.2.2 目录:

/bin

存放所有用户都可以使用的、基本的命令;

比须和根文件系统在一个分区中。

/sbin

存放系统命令,只有管理员可以使用的命令

必须和根文件系统在同一分区中。

/---/sbin

*基本的系统命令,用于启动系统、修复系统等。

*---/usr/sbin

*不是急迫需要使用的系统命令。

*---/usr/local/sbin

/本地安装的系统命令。

/dev:存放设备文件。

/etc:存放配置文件。

/lib

/---libc.so.*动态链接C库。

*---ld*链接器、加载器。

/---modules内核可加载模块存放的目录。

/home:用户目录。

/root:根用户目录。

/usr

存放共享、只读的数据和程序;

可以存放在另一个分区中,系统启动后再挂接到根文件系统的/usr目录下。

/var:存放可变的数据。

/proc

proc文件系统的挂接点;

proc文件系统是一个虚拟的文件系统,用来表示系统的运行状态。

/mnt:用于临时挂接某个文件系统的挂接点。

/tmp

用于存放临时文件;

为减少对Flash的操作,可以在/tmp目录上挂接内存文件系统。

2. Busybox

2.1 init进程

2.1.1 定义

由内核启动的第一个(唯一的一个)用户进程(ID=1);

是后续所有进程的发起者,根据配置文件决定启动哪些程序;

执行的程序通常是/sbin/init,也可以传入命令行参数指定一个程序作为init进程运行。

2.1.2 内核如何启动init进程

内核启动的最后一步是启动init进程,代码在linux内核源码的init/main.c中。static int noinline init_post(void)

{

free_initmem();

unlock_kernel();

mark_rodata_ro();

system_state = SYSTEM_RUNNING;

numa_default_policy();

/*打开标准输入(stdin)、标准输出(stdout)、标准错误(stderr);

*对应的文件描述符分别是0,1,2。

*/

//打开/dev/console设备文件,他是init进程的标准输入设备。

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

//将文件描述符0复制给文件描述符1,2;

//标准输入、标准输出、标准错误对应同一个文件(设备)。

(void) sys_dup(0);

(void) sys_dup(0);

/*ramdisk_execute_command

*指定了要执行的程序

*1. ”

如果命令行参数中指定了rdinit=...”

*ramdisk_execute_command等于此指定值。

*2. 如果/init程序存在

*ramdisk_execute_command=/init

*3. ramdisk_execute_command为空。

*/

if (ramdisk_execute_command) {

/*run_init_process函数

*使用他的参数所指定的程序来创建一个用户进程;

*一旦创建进程成功,此函数将不会返回。

*/

run_init_process(ramdisk_execute_command);

printk(KERN_WARNING "Failed to execute %s\n",

ramdisk_execute_command);

}

/*execute_command

*指定了要执行的程序

*1. ”

如果命令行参数中指定了init=...”

* execute_command等于此指定值。

*2. execute_command为空

*/

if (execute_command) {

run_init_process(execute_command);

printk(KERN_WARNING "Failed to execute %s. Attempting "

"defaults...\n", execute_command);

}

//依次尝试执行/sbin/init、/etc/init、/bin/init、/bin/sh。

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.");

}

static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };

char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };

static void run_init_process(char *init_filename)

{

argv_init[0] = init_filename;

kernel_execve(init_filename, argv_init, envp_init);

}

2.1.3 Busybox init程序流程

设置信号处理函数;

初始化控制台;

解析inittab。

2.1.4 初始化控制台

进程时打开了/dev/console”设备作为控制台,一般情况下Busybox init程内核启动init”

序使用/dev/console;

如果内核启动init进程时设置了环境变量CONSOLE或是console,则使用环境变量所指定

程序中,会检查这个设备是否可以打开,如果不能打开则使用/dev/null”。的设备。Busybox init”

2.1.5 解析/etc/inittab文件

/etc/inittab文件中的每个条目用来定义一个子进程,并确定他的启动方法。

格式:

:::

:这个子进程要使用的控制台,若省略则使用与init进程一样的控制台。

:对Busybox init程序无意义,省略。

:要执行的程序,可以是可执行程序,或是脚本;

如果程序是交互的,字段前加上-”字符。

:表示init进程如何控制这个子进程

/*sysinit

*系统启动后最先执行,只执行一次;

*init进程等他结束后继续执行其他动作。

*wait

*系统执行完sysinit后,只执行一次;

*init进程等他结束后继续执行其他动作。

*once

*系统执行完wait进程后,只执行一次;

相关文档
最新文档