小结:(1)u-boot:启动内核,并向内核传递参数,如如何挂载文件系统(从硬盘还是网络),及各种地址参数;(2)内核:管理功能,启动应用程序(ls等命令都是应用程序,应用程序位于根文件系统);(3)构建根文件系统
在存储其中构建跟文件系统的方式:(1)在PC中开发生成某种文件系统镜像然后通过u-boot下载及传参数给内核。(2)在PC中建立目录作为挂载存储器分区的点,通过busybox在此目录下构建所需的应用程序,如ls,mount,ps等命令,及其需要的文件。(3)完成其他配置文件;(4)通过该文件系统格式对应的工具把这个目录编译成镜像文件;(5)通过u-boot烧写;(6)选择执行busybox中应用程序
最小根文件系统根文件系统:init本身就是busybox;/dev/console; /dev/null; /etc/inittab; 配置文件里面inittab指定的应用程序;应用程序需要的C库
1、类似windows下的C、D等盘,Linux也会把磁盘、Flash化分成若干个分区。内核镜像文件(一般单独存放在一个分区中)。
内核启动后运行的第一个程序init、给用户提供界面的shell程序、应用程序依赖的库。这些必需、基本的文件合称根文件系统。Linux启动后首先要挂接这个根文件系统。
2、linux以树状结构管理目录和文件,其他分区挂接在某个目录上(挂接点),然后就可以通过这个目录进行访问。
制作根文件系统,就是创建各种目录,并在里面创建各种文件。
制作文件系统镜像,就是把一个目录下所有内容按照一定的格式存放到一个文件中,把这个文件直接烧到存储设备上。当系统启动后,挂载这个设备就可以看到和原来目录一样的内容。
3、一个分区上存储文件时,遵循的规则为文件系统类型。嵌入式系统中,jffs文件系统用于Nor Flash。yaffs用于Nand Flash
Linux还有几种虚拟文件系统,如proc、sysfs,它们不存储在实际的设备上,而是访问它们时由内核临时生成。
4、Linux根文件系统目录结构
(1)/bin用户命令
(2)/sbin系统命令
(3)/etc系统管理的各种配置文件
/etc/passwd用户数据库,用户起始目录、加密口令和用户的其他信息。
/etc/fstab指定启动时需要自动安装的文件系统列表。也包括用swapon -a启用的swap区的信息。
/etc/inittab init的配置文件,init进程根据其来创建其他进程。
(4)/home普通用户目录
(5)/root根用户目录
(6)/usr共享、只读程序和数据,用户的很多应用程序和文件都存放在这个目录下。
/usr/bin存放着许多应用程序;
/usr/sbin存放root超级用户使用的管理程序;
(7)/var可变的数据,如log文件、临时文件,/var/www
(8)/boot启动时需要用到的程序
5、文件类型
- 普通文件
d 目录
c 字符设备
b 块设备
p 管道(用于进程间通信)
s 套接字(用于进程间网络通信)
l 符号链接
6、init进程是内核启动的第一个,也是唯一一个用户进程,它根据配置文件决定启动哪些程序。init进程的执行程序通常是/sbin/init。
init/main.c下内核启动的最后一步就是启动init进程
static int noinline init_post(void)
{
free_initmem();
unlock_kernel();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
//打开控制台,标准输入、输出、错误设备
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);
//run_init_process执行应用程序,ls等命令都是应用程序
//如果命令行有传入具体控制台,就执行该进程,不会返回
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
//执行进程/sbin/init,不成功则往下执行
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.");
}
7、嵌入式系统中busybox是ls等命令的合集(即应用程序的合集)
# ls -l /bin/ls
lrwxrwxrwx 1 1000 1000 7 Feb 12 2017 /bin/ls -> busybox
//进程/sbin/init也是到busybox的连接
# ls /sbin/init -l
lrwxrwxrwx 1 1000 1000 14 Feb 12 2017 /sbin/init -> ../bin/busybox
注意是嵌入式设备中而不是PC中
/sbin/init中init程序:(1)读取配置文件;(2)解析配置文件;(3)根据配置文件执行用户程序
busybox->
init_main->
parse_inittab->
file = fopen(INITTAB, "r");//打开配置文件
new_init_action;//根据配置文件执行
run_actions(SYSTEM)->//运行一类动作,类指的是
waitfor(a, 0);//等待一个执行完,然后删掉,SYSTEM类型只执行一次
delete_init_action(a);
//inittbl格式:
<id>::: //如s3c2410_serial0::askfirst:-/bin/sh
id=/dev/id,用作终端(输入输出)
何时执行
应用程序或者脚本
static void parse_inittab(void)
{
#if ENABLE_FEATURE_USE_INITTAB
FILE *file;
char buf[INIT_BUFFS_SIZE], lineAsRead[INIT_BUFFS_SIZE];
char tmpConsole[CONSOLE_NAME_SIZE];
char *id, *runlev, *action, *command, *eol;
const struct init_action_type *a = actions;
file = fopen(INITTAB, "r");
if (file == NULL) {
/* No inittab file -- set up some default behavior */
#endif
/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");
/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");
/* Swapoff on halt/reboot */
if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
/* Prepare to restart init when a HUP is received */
new_init_action(RESTART, "init", "");
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");
//如new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2");创建下面结构放入链表
struct init_action {
struct init_action *next;
int action;
pid_t pid;
char command[INIT_BUFFS_SIZE];
char terminal[CONSOLE_NAME_SIZE];
};
8、busybox使用
//在界面中选择需要的命令(程序)
make menuconfig # This creates a file called ".config"
make # This creates the "busybox" executable
//安装到开发板的某个目录
make CONFIG_PREFIX=/path/from/root install