文件系統學習(3)

一、說在前面:在嵌入式中呢,首先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/sh
ifconfig eth0 192.168.1.110
mount -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 所檢查。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章