根檔案系統簡介與BusyBox構建根檔案系統

lethe1203發表於2024-03-22
參考資料:
https://www.bilibili.com/video/BV12E411h71h?p=43&vd_source=432ba293ecfc949a4174ab91ccc526d6

根檔案系統簡介:

根檔案系統也成為rootfs,fatfs這類的檔案系統屬於Linux核心的一部分,屬於軟體程式碼
如果沒根檔案系統,核心會出現kernel panic。根檔案系統就是一堆檔案,比如軟體、配置檔案等,這些檔案是linux執行所必須的,將他們組合在一起就構成了根檔案系統
如ubuntu上/目錄:
0
百度百科關於根檔案系統的描述:
根檔案系統首先是核心啟動時所 mount(掛載)的第一個檔案系統,核心程式碼映像檔案儲存在根檔案系統中,而系統引導啟動程式會在根檔案系統掛載之後從中把一些基本的初始化指令碼和服務等載入到記憶體中去執行。
百度百科上說核心程式碼映象檔案儲存在根檔案系統中,但是我們嵌入式 Linux 並沒有將核心程式碼映象儲存在根檔案系統中,而是儲存到了其他地方。比如 NAND Flash 的指定儲存地址、EMMC 專用分割槽中。根檔案系統是 Linux 核心啟動以後掛載(mount)的第一個檔案系統,然後從根檔案系統中讀取初始化指令碼,比如 rcS,inittab 等。根檔案系統和 Linux 核心是分開的,單獨的 Linux 核心是沒法正常工作的,必須要搭配根檔案系統。如果不提供根檔案系統,Linux 核心在啟動的時候就會提示核心崩潰(Kernel panic)的提示
根檔案系統的這個“根”字就說明了這個檔案系統的重要性,它是其他檔案系統的根,沒有這個“根”,其他的檔案系統或者軟體就別想工作。比如我們常用的 ls、mv、ifconfig 等命令其實就是一個個小軟體,只是這些軟體沒有圖形介面,而且需要輸入命令來執行。這些小軟體就儲存在根檔案系統中

根檔案系統目錄和檔案介紹:

/bin:可執行檔案,常用的一些軟體,如ls
/etc:跟配置相關的檔案
/lib:庫檔案,系統軟體執行,如gcc
/mnt:掛載目錄
/proc:存在系統執行時的資訊
/sys:sysfs 檔案系統的掛載點
/dev:所以此目錄下的檔案都是和裝置有關的,此目錄下的檔案都是裝置檔案
/var:一些可變資料
/usr:Unix Software Resource,unix作業系統軟體資源目錄
/opt:可選的檔案、軟體存放區
/sbin:使用者存放一些可執行檔案,但是此目錄的檔案或者命令只有管理員才能使用
/tmp:臨時檔案
根檔案系統構建方式有:busybox、buildroot、yocto

BusyBox:

網址:https://busybox.net/
此處構建出來的根檔案系統除錯使用nfs掛載,也就是根檔案系統放在ubuntu下,開發板啟動以後透過nfs服務使用ubuntu下的根檔案系統

1、修改Makefile,新增ARCH和CROSS_COMPILE

2、busybox支援中文字元,在libbb/printable_string.c檔案中修改

0
libbb/unicode.c檔案中修改:
0

3、配置busybox

使用make defconfg進行預設配置,如果生成.config就表示配置成功了
make menuconfig進行配置
0

4、編譯busybox

配置好busybox以後就可以編譯了,可以指定編譯結果的存放目錄,如下:
make install CONFIG_PREFIX=/home/lethe/linux/nfs/rootfs
busybox原始碼編譯完成之後會生成bin linuxrc sbin usr四個目錄

5、複製庫檔案

新增/lib庫
將arm-linux-gnueabihf/libc/lib資料夾複製到rootfs/lib下
在複製時需要加-d,-d表示符號連結
0
再將arm-linux-gnueabihf/lib也複製到rootfs/lib下
新增/usr/lib
將arm-linux-gnueabihf/libc/usr/lib複製到rootfs/usr/lib下
可透過du ./lib ./usr/lib -sh檢視lib和usr/lib目錄的大小

6、建立其他根檔案系統資料夾

dev proc mnt sys tmp root

7、nfs掛載根檔案系統

  • 要求linux核心網路驅動要工作正常
  • 設定uboot的bootargs,也就是linux核心的命令列引數
rw如果沒有設定在開發板中touch會出現read-only檔案系統
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.31.230:/home/lethe/linux/nfs/rootfs,proto=tcp rw ip=192.168.31.62:192.168.31.230:192.168.1.1:255.255.255.0::eth0:off'
0

8、根檔案系統完善

/etc/init.d/rcS檔案

can't run '/etc/init.d/rcS': No such file or directory
/etc/init.d/rcS是一個shell指令碼,Linux核心啟動之後需要啟動一些服務,rcS就是規定啟動哪些檔案的指令碼檔案,rcS內容如下:
#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH            // 可執行檔案可能存在的目錄,$PATH表示追加的
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib        // 相關庫的路徑,表示加入/lib和/usr/lib兩個路徑
export PATH LD_LIBRARY_PATH                         // 將可執行檔案和相關庫的路徑匯出
mount -a                                            // 自動掛載所有支援掛載的裝置,這些系統檔案由檔案/etc/fstab來指定
mkdir /dev/pts                                        // 將devpts掛載到/dev/pts中
mount -t devpts devpts /dev/pts

echo /sbin/mdev > /proc/sys/kernel/hotplug            // 使用mdev實現熱插拔,透過這兩行,Linux 核心就可以在/dev 目錄下自動建立裝置節點
mdev -s

/etc/fstab檔案

再次重啟之後會提示:
can't read '/etc/fstab': No such file or directory
/etc/fstab在linux開機之後自動配置哪些需要自動掛載的分割槽,格式如下:
<file system> <mount point> <type> <options> <dump> <pass>
file system:要掛載的特殊的裝置,也可以是塊裝置,比如/dev/sda 等等。
mount point:掛載點。
type:檔案系統型別,比如 ext2、ext3、proc、romfs、tmpfs 等等。
options:掛載選項,在 Ubuntu 中輸入“man mount”命令可以檢視具體的選項。一般使用 defaults,也就是預設選項,defaults 包含了 rw、suid、 dev、 exec、 auto、 nouser 和 async。
dump:為 1 的話表示允許備份,為 0 不備份,一般不備份,因此設定為 0。
pass:磁碟檢查設定,為 0 表示不檢查。根目錄‘/’設定為 1,其他的都不能設定為 1,其他的分割槽從 2 開始。一般不在 fstab 中掛載根目錄,因此這裡一般設定為 0。
fstab檔案輸入以下內容:
#<file system> <mount point> <type> <options> <dump> <pass>
proc             /proc         proc defaults     0     0
tmpfs             /tmp         tmpfs defaults     0     0
sysfs             /sys         sysfs defaults     0     0

/etc/inittab檔案

最終還需要建立一個/etc/inittab檔案:
inittab 的詳細內容可以參考 busybox 下的檔案 examples/inittab。init 程序會讀取/etc/inittab這個檔案,inittab 由若干條指令組成。每條指令的結構都是一樣的,由以“:”分隔的 4 個段組成,格式如下:
<id>:<runlevels>:<action>:<process>
id:每個指令的識別符號,不能重複。但是對於 busybox 的 init 來說,有著特殊意義。對於 busybox 而言用來指定啟動程序的控制 tty,一般我們將串列埠或者 LCD 螢幕設定為控制 tty。
runlevels:對 busybox 來說此項完全沒用,所以空著。
action:動作,用於指定可能用到的動作。
busybox 支援的動作如下:
0
process:具體的動作,比如程式、指令碼或命令等。
建立一個/etc/inittab,在裡面輸入如下內容:
#etc/inittab
::sysinit:/etc/init.d/rcS            // 系統執行之後執行/etc/init.d/rcS指令碼檔案
console::askfirst:-/bin/sh            // 將console作為控制檯終端
::restart:/sbin/init                // 重啟會執行/sbin/init
::ctrlaltdel:/sbin/reboot            // ctrl+alt+del組合鍵會執行/sbin/reboot
::shutdown:/bin/umount -a -r        // 關機的時候執行/bin/umount
::shutdown:/sbin/swapoff -a           // 關機的時候執行/sbin/poweroff,也就是關閉交換分割槽

相關文章