構建根文件系統

一、先來分析下busybox
在根文件系統中有很多命令,如ls、cp等等,每個命令都相當於應用程序,若它有很多命令的話,我們一個個去把應用程序找出來然後編譯是很麻煩的事情。
在嵌入式系統中有一個busybox,它就是如ls、cp等等這些命令的組合,當我們去編譯busybox的時候會得到一個 叫busybox的應用程序(這時如ls、cp等等這些命令都是它的符號鏈接),當我們再去執行命令時,其實就是在執行busybox程序。例如當在根文件系統下輸入ls -l /bin/ls 便會發現 /bin/ls -> busybox。
同樣的道理內核啓動的第一個應用程序init也是busybox程序的符號鏈接,可以通過 ls -l /sbin/init查看(所以想確定init做了那些事情,就要去分析busybox源碼)打開init/init.c文件可以發現busybox調用了init_main ,調用關係如下在這裏插入圖片描述在這裏插入圖片描述
注:打開examples/inittab文件發現其格式爲::::,其中id項最終會加上一個/dev, 即/dev/id,用作終端(stdin,stdout,stderr:printf,scanf,err),若不設置id的話就對應/dev/null;runlevels可以完全忽略;action用來指示何時執行;process表示應用程序或腳本。

由以上不難看出,一個最小根文件系統應該滿足如下要求:
1)/dev/console /dev/null
2)init應用程序(一般來源於busybox);init程序運行時需要讀的配置文件 /etc/inittab ;配置文件中指定的應用程序。
3)爲程序運行提供函數的庫(若當在make menuconfig的時候若將Build Options設置爲靜態的,那就可以不需要這裏的庫了,除非客戶的應用程序需要)

二、下面便一步步來構建最小根文件系統
1、編譯busybox
將busybox解壓後通過閱讀INSTALL文件便可知道編譯方法,這裏就像編譯內核一樣,編譯前交叉編譯工具鏈要選擇好。若使用交叉編譯的話,在編譯完安裝的時候就千萬不要直接make install,因爲這樣做的話就會直接安裝到PC機上了,這樣有可能把PC機破換。要把它安裝在一個指定目錄裏,譬如/work/nfs_root/fs_mini。
在這裏插入圖片描述
安裝完成後進入/work/nfs_root/fs_mini,用ls命令就會發現裏面有一個文件linuxrc(它是busybox的符號鏈接,即linuxrc -> busybox)與三個文件夾(bin(裏面的命令也是指向busybox的),sbin和usr)

2、在/work/rootfs下創建設備文件
創建設備文件前,首先我們先看下服務器上 /dev/console 和 /dev/null的信息如下(其中c表示爲字符設備,5表示主設備號,1表示次設備號)
在這裏插入圖片描述
下面我們來創建:
mkdir dev
cd /dev
sudo mknod console c 5 1
sudo mknod null c 1 3

3、在/work/nfs_root/fs_mini下構造inttab
若不構造的話,它就會有一個默認的配置項(我們並不需要默認的配置項)。
mkdir etc
vi etc/inittab 然後可以裏面輸入一句內容(如 console::askfirst:~/bin/sh)

4、在/work/nfs_root/fs_mini下構造庫
mkdir lib
其中-d表示如果原來有鏈接文件,當拷貝過來後仍然保持爲鏈接文件,如果不加-d的話就會拷貝真是所指向的文件,這樣拷貝過來的庫就會很大。.so表示動態鏈接庫(我們用動態鏈接庫)

以上完成後 用ls命令查看,包含了 bin sbin usr linuxrc dev etc lib
這便構建了最小根文件系統(配置文件中還沒指定應用程序),當用工具把它做成一個映像文件後便可以燒到開發板中去。燒寫到最後可以看到如下的打印信息,回車後就會啓動那個應用程序,這就和我們在第3步的時候的對應上了(這裏inittab中 只有一項)
在這裏插入圖片描述
用ls命令便可看到文件信息
在這裏插入圖片描述

三、完善最小根文件系統
1、例如當輸入一個命令,如ps命令後就提示沒有 /proc這個目錄 :那我們就mkdir proc,但是即使有了proc這個目錄還是不夠的(當執行ps時還是沒有任何東西,如下圖所示)。這是由於內核提供一個虛擬的文件系統proc來收集有哪些應用程序在跑,手工掛載後,用ps命令就會進到如下的/proc目錄下就能看到有哪些程序,有那些內容。如下用cd進入到內核提供的虛擬文件系統/proc就可看到如下信息
在這裏插入圖片描述
若不想手工掛載的話,可以加個配置文件,譬如說,在inttab中把原來加的那句刪除,只加如下的一句
在這裏插入圖片描述
創建腳本文件/etc/init.d/rcs 後,在rcs中加入mount -t proc none /proc這句話,加完後賦予權限
在這裏插入圖片描述
這樣當文件再重新燒到開發板啓動後,就會去執行/etc/init.d/rcs,進而執行mount -t proc none /proc,如果想增加其他命令的時候也可以在裏面加上去
2、除了以上mount -t 的方法外,還有一種方法:在上面的基礎上將mount -a這句話加入etc/init.d/rcs,然後再創建一個文件/etc/fstab,將以下內容寫入fstab(mount -a 它會讀出/etc/fstab,根據這個配置文件中的內容指示來掛載文件系統)
在這裏插入圖片描述
再次做成映像文件,燒錄啓動後,在最後就可 看到如下,當用ps命令就會發現有效果了;用cat /proc/mounts可以查看,當前掛載了那些文件系統
在這裏插入圖片描述

四、繼續完善這個根文件系統
此時,/dev下只有console和null。我們知道 /dev目錄下的東西是對應於那些設備,那些驅動的,試想一下若有成千上完個設備驅動的話,一個一個去創建這些 /dev目錄的話就太麻煩了。而udev機制可以自動創建 /dev目錄下的設備節點,在busybox裏面有一個udev的簡化版本叫mdev。其中docs/medv.txt便是使用方法。
在這裏插入圖片描述
操作如下:
mkdir sys
在etc/fstab中增加:
在這裏插入圖片描述
在/etc/init.d/rcs 中增加:這裏medv -s中的-s表示一開始的時候就先把原先內核現有的那些驅動的設備節點都創建出來。
在這裏插入圖片描述

再次製作燒錄根文件系統鏡像啓動後查看 /dev目錄下就會有很多的設備文件了,這都是medv爲我們創建的,並且也掛載了很多文件系統,如下:
在這裏插入圖片描述

到這裏的話這個最小的根文件系統就比較完善了

五:掛載NFS
從上面的操作可以看出每做一次就燒寫一次,那麼有沒有辦法不讓每次都燒寫呢?這就要用到網絡文件系統NFS。掛載NFS
情況一:從flash上啓動根文件系統後去掛載
需要滿足二個條件:
1、服務器”允許“那個目錄可被別人掛接,即nfs服務
服務器的nfs配置文件在/etc/exports,將要被掛載的共享文件目錄譬如/work/nfs_root/fs_mini放入該配置文件後重啓服務即可(可以在服務器上試一下自己掛接自己,譬如 sudo mount -t nfs 172.16.104.33:/work/nfs_root/fs_mini /mnt)。
2、開飯板去掛接
在開發板上根文件系統下創建一個目錄,如 mkdir mnt
然後 mount -t nfs -o nolock 172.16.104.33:/work/nfs_root/fs_mini /mnt
此時在開發板上執行 ls /mnt所看到的東西就和在服務器上/work/nfs_root/fs_mini目錄下的東西是一樣的,例如在服務器上echo hello >test.txt,則在開發板的/mnt 目錄下也能看到test.txt

情況二:直接從nfs啓動
需要修改uboot 命令行bootargs參數:服務器IP,目錄;設置開發板自己的IP等,其在內核的Documentation/nfsroot.txt可以查看,有固定的格式。

可以做個小測試,比如
當在網絡文件系統啓動後,可以寫一個應用程序hello.c
然後編譯 arm-linux-gcc -o hello hello.c
就可以直接 ./hello

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章