文件系统学习(3)

来源:互联网 发布:美团数据采集 编辑:程序博客网 时间:2024/06/03 22:46

一、说在前面:在嵌入式中呢,首先uboot的最终目的是启动我们的内核,内核的目的是启动我们的应用程序。怎么启动的呢?
我们来分析下init_post()这个函数;

static int noinline init_post(void){    .......    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);//这两个函数进行文件描述符的复制,最终使得我们的标准输入、输出、出错都对应同一个设备文件。    .......    if (execute_command) {        run_init_process(execute_command);        printk(KERN_WARNING "Failed to execute %s.  Attempting "                    "defaults...\n", execute_command);    }//如果uboot中的bootargs中有设置init,if就会被执行。而且不带返回。    run_init_process("/sbin/init");    run_init_process("/etc/init");    run_init_process("/bin/init");    run_init_process("/bin/sh");    //如果bootargs中没设置init,内核就会执行以上目录中的init之一    panic("No init found.  Try passing init= option to kernel.");    //如果都没有init程序,内核启动失败}

二、根文件系统的构建
对于嵌入式根文件系统的构建,从零开始构建不太现实,我们利用busybox这开源项目来构建我们根文件系统中的各个目录以及所需的文件。我们自己在其基础进行添加修改,形成最终我们想要的根文件系统。

busybox中init程序分析(linuxrc)

  1. 读取配置文件
  2. 解析配置文件
  3. 执行用户程序
int init_main(int argc, char **argv){    ......    //设置信号处理函数,即有什么信号过来或发送,就执行相应的函数    signal(SIGHUP, exec_signal);    signal(SIGQUIT, exec_signal);    signal(SIGUSR1, shutdown_signal);    signal(SIGUSR2, shutdown_signal);    signal(SIGINT, ctrlaltdel_signal);    signal(SIGTERM, shutdown_signal);    signal(SIGCONT, cont_handler);    signal(SIGSTOP, stop_handler);    signal(SIGTSTP, stop_handler);    ......    console_init();//终端设备初始化    ......    if (argc > 1     && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))    ) {        /* Start a shell on console */        new_init_action(RESPAWN, bb_default_login_shell, "");    } else {        /* Not in single user mode -- see what inittab says */        /* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,         * then parse_inittab() simply adds in some default         * actions(i.e., runs INIT_SCRIPT and then starts a pair         * of "askfirst" shells *///new_init_action函数:创建一个init_action结构,并填充,然后加入init_action_list链表        parse_inittab();//从/etc/inittab文件中读取,并加入init_action_list链表,    }......    run_actions(SYSINIT);//run_actions函数执行相关命令,即从init_action_list中读取init_action结构,不同命令不同执行执行方式。对于RESPAWN | ASKFIRST命令有退出则重新执行。具体命令作用看源码。.......}

/etc/inittab文件

id : runlevels : action : process

id:终端设备:/dev/id
runlevels:这一项忽略
action :何时执行process
process:应用程序或脚本

/etc/init.d/rcS文件
这是一个脚本文件,可以在里面添加我们想自动执行的命令,比如配置ip地址,挂载/etc/fstab中的指定的文件系统

#!/bin/shifconfig eth0 192.168.1.110mount -a #这条命令是指挂载/etc/fstab 中指定的文件系统

注:rcS文件是可执行的,是在inittab文件中指定的,若不能执行则
chmod +x /etc/init.d/rcS

/etc/fstab文件
该文件指定需要挂载的文件系统,当rcS文件被执行到mount -a时,相应的文件系统被挂载。
让我们对fstab的用法进行一个详细的了解。一个典型的entry有下面的fields (fields用空格或tab分开):
这里写图片描述

  • file systems 要挂载的分区或存储设备.
  • dir 是 file systems的挂载位置。
  • type 要挂载设备或是分区的文件系统类型,支持许多种不同的文件系统:ext2, ext3, ext4, reiserfs, xfs,
    jfs, smbfs, iso9660, vfat, ntfs, swap 及 auto。 设置成auto类型,mount
    命令会猜测使用的文件系统类型,对 CDROM 和 DVD 等移动设备是非常有用的。
  • options 挂载时使用的参数,注意有些mount 参数是特定文件系统才有的。一些比较常用的参数有: auto - 在启动时或键入了
    mount -a 命令时自动挂载。 noauto - 只在你的命令下被挂载。 exec - 允许执行此分区的二进制文件。 noexec -
    不允许执行此文件系统上的二进制文件。 ro - 以只读模式挂载文件系统。 rw - 以读写模式挂载文件系统。 user -
    允许任意用户挂载此文件系统,若无显示定义,隐含启用 noexec, nosuid, nodev 参数。 users - 允许所有
    users 组中的用户挂载文件系统. nouser - 只能被 root 挂载。 owner - 允许设备所有者挂载. sync -
    I/O 同步进行。 async - I/O 异步进行。 dev - 解析文件系统上的块特殊设备。 nodev -
    不解析文件系统上的块特殊设备。 suid - 允许 suid 操作和设定 sgid
    位。这一参数通常用于一些特殊任务,使一般用户运行程序时临时提升权限。 nosuid - 禁止 suid 操作和设定 sgid 位。
    noatime - 不更新文件系统上 inode 访问记录,可以提升性能(参见 atime 参数)。 nodiratime -
    不更新文件系统上的目录 inode 访问记录,可以提升性能(参见 atime 参数)。 relatime - 实时更新 inode
    access 记录。只有在记录中的访问时间早于当前访问才会被更新。(与 noatime 相似,但不会打断如 mutt
    或其它程序探测文件在上次访问后是否被修改的进程。),可以提升性能(参见 atime 参数)。 flush - vfat
    的选项,更频繁的刷新数据,复制对话框或进度条在全部数据都写入后才消失。 defaults - 使用文件系统的默认挂载参数,例如 ext4
    的默认参数为:rw, suid, dev, exec, auto, nouser, async.
  • dump dump 工具通过它决定何时作备份. dump 会检查其内容,并用数字来决定是否对这个文件系统进行备份。 允许的数字是 0 和
    1 。0 表示忽略, 1 则进行备份。大部分的用户是没有安装 dump 的 ,对他们而言 dump 应设为 0。
  • pass fsck 读取 pass 的数值来决定需要检查的文件系统的检查顺序。允许的数字是0, 1, 和2。
    根目录应当获得最高的优先权 1, 其它所有需要被检查的设备设置为 2. 0 表示设备不会被 fsck 所检查。
原创粉丝点击