目錄
概述
本文記錄了根檔案系統的一些知識點,Busybox 工具的使用和 最小根檔案系統的製作。
概念
根檔案系統是什麼
根檔案系統是特殊用途的檔案系統,必須屬於某種檔案系統格式。那麼檔案系統是用來幹嘛的?
- 首先,儲存裝置(塊裝置,像硬碟、 flash 等) 是分塊(扇區)的,物理上底層去訪問儲存裝置時是按照塊號(扇區號)來訪問的。這就很麻煩。
- 其次,檔案系統是一些程式碼,是一套軟體,這套軟體的功能就是對儲存裝置的扇區進行管理,將這些扇區的訪問變成了對目錄和檔名的訪問。我們在上層按照特定的目錄和檔名去訪問一個檔案時,檔案系統會將這個目錄 + 檔名轉換成對扇區號的訪問。
- 最後,不同的檔案系統的差異在於對這些扇區的管理策略和方法不同,如壞塊管理、 碎片管理。
根檔案系統中有什麼
- 最重要的就是 linuxrc
- dev 目錄下的裝置檔案。在 linux 中一切皆是檔案,硬體裝置被虛擬化成一個裝置檔案。
- sys 和 proc 目錄。可以為空但是必須有,和驅動有關。 屬於 linux 中的虛擬檔案系統。
- etc 目錄。存放執行時配置檔案。 /etc 目錄下的所有配置檔案會直接或者間接的被 /linuxrc 所呼叫執行,完成作業系統的執行時配置。 etc 目錄是製作 rootfs 的關鍵。
- lib 目錄下放的是當前作業系統中的動態和靜態連結庫檔案。
根檔案系統的形式
-
映象檔案形式
- 使用專用工具軟體製作的可供燒錄的映象檔案
- 映象中包含了根檔案系統中的所有檔案
- 燒錄此映象類似於對相應分割槽格式化。
- 映象檔案系統具有一定的格式,格式是內化的,跟檔名字尾是無關的。
-
資料夾形式
- 根檔案系統其實就是一個包含特定內容的資料夾而已
- 根檔案系統可由任何一個空資料夾新增必要檔案構成而成
- 根檔案系統的雛形就是在開發主機中構造的資料夾形成的
-
總結
-
映象檔案形式的根檔案系統主要目的是用來燒錄到塊裝置上,裝置上的核心啟動後去掛載它。映象檔案形式的根檔案系統是由資料夾形式的根檔案系統使用專用的映象製作工具製作而成的。
-
最初在開發主機中隨便 mkdir 建立了一個空資料夾,然後向其中新增一些必要的檔案(包括etc 目錄下的執行時配置檔案、/bin 等目錄下的可執行程式、 /lib 目錄下的庫檔案等···)後就形成了一個資料夾形式的 rootfs。 然後這個資料夾形式的 rootfs 可以被 kernel 通過 nfs 方式來遠端掛載使用,但是不能用來燒錄塊裝置。我們為了將這個 rootfs 燒錄到塊裝置中,於是用一些專用的軟體工具,將其製作成可供燒錄的一定格式的根檔案系統映象。
-
資料夾形式的 rootfs 是沒有格式的,製作成映象後就有了一定的 rootfs 格式了, 格式是由我們的映象製作過程和製作工具來決定的。 每一種格式的映象製作工具的用法都不同。
-
Busybox 簡介
-
busybox是一個C語言寫出來的專案,裡面包含了很多.c檔案和.h檔案。
-
busybox 這個程式開發出來就是為了在嵌入式環境下構建根檔案系統(以下簡稱 rootfs)使用的,也就是說他就是專門開發的 init 程式應用程式。
-
busybox 為當前系統提供了一整套的 shell 命令程式集。譬如 vi、cd、mkdir、ls 等。在桌面版的 linux 發行版(譬如 ubuntu、redhat等)中 vi、cd、ls 等都是一個一個的單獨的應用程式。但是在嵌入式 linux 中,為了省事我們把 vi、cd 等所有常用的 shell 命令集合到一起構成了一個 shell 命令包,起名叫 busybox。
-
Busybox 在編寫過程中對檔案大小進行了優化,並考慮了系統資源有限(比如記憶體等)的情況。與一般的 GNU 工具集動輒幾 M 的體積相比,動態連結的 Busybox 只有幾百 K,即使是採用靜態連結也只有1 M 左右。Busybox 按模組設計,可以很容易地加入、去除某些命令,或增減命令的某些選項。
什麼是 linuxrc
- linuxrc 是一個可執行的應用程式。 是應用層的,和核心原始碼一點關係都沒有。
- linuxrc 如果是靜態編譯連線的那麼直接可以執行;如果是動態編譯連線的那麼我們還必須給他提供必要的庫檔案才能執行。但是因為我們 linuxrc 這個程式是由核心直接呼叫執行的, 因此使用者沒有機會去匯出庫檔案的路徑,因此實際上 linuxrc 沒法動態連線,一般都是靜態連線的。
- linuxrc 執行時引出使用者介面。作業系統啟動後在一系列的自檢執行配置之後,最終會給使用者一個操作介面(cmdline 或 GUI),這個使用者操作介面就是由 /linuxrc 帶出來的。使用者介面等很多事並不是在 /linuxrc 程式中負責的,使用者介面有自己專門的應用程式,但是使用者介面的應用程式是直接或者間接的被 linuxrc 呼叫執行的。使用者介面程式和其他的應用程式就是程式 2、3、4 ···,這就是我們說的程式 1(init 程式,也就是 /linuxrc)是其他所有應用程式程式的祖宗程式。
- linuxrc 負責系統啟動後的配置。作業系統啟動起來後也不能直接用,要配置下。作業系統啟動後的應用層的配置(一般叫執行時配置,英文簡寫 etc),是為了讓我們的作業系統用起來更方便,更適合個人的愛好或者實用性。
VFS 簡介
-
VFS 是 linux 核心的一種設計理念、設計機制。全拼 vitrual file system,叫虛擬檔案系統。
-
具體的一些檔案系統如 FAT、 NTFS、 ext2、 ext3、 jffs2、 yaffs2、 ubi 等主要設計目的是為了管理塊裝置(硬碟、 Nand···)
-
VFS 是借鑑了檔案系統的設計理念(通過檔案系統將底層難以管理的物理磁碟扇區式訪問,轉換成目錄 + 檔名的方式來訪問),將硬體裝置的訪問也虛擬化成了對目錄 + 檔案的訪問。所以有了 VFS 後我們可以通過裝置檔案(如/dev/mmcblk0p2) 的方式來訪問系統中的硬體裝置。
-
VFS 將對硬體裝置的訪問和對普通檔案的訪問給介面統一化了(linux 中一切皆是檔案)。VFS 成了一個隔離層,隔離了下層的不同檔案系統的差異性,對上層應用提供一個統一的介面。
-
VFS 將不同檔案系統和下層硬體裝置(塊裝置)驅動之間的細節也給遮蔽了。不同型別的檔案系統在本身設計時是 不用考慮各種不同的硬體裝置的具體操作差異的,這裡有一個類似於 VFS 的設計理念。
-
VFS 機制和 rootfs 掛載與其他檔案系統的掛載都是有關聯的。核心中有一些 sys proc 這種虛擬檔案系統,也是和 VFS 機制有關。 /dev/目錄下的裝置檔案都和 VFS 有關。
Busybox 工具
Busybox 目錄結構
目錄 | |
---|---|
applets | 主要是實現applets框架的檔案 |
applets_sh | 一些有用的指令碼,例如:dos2unix、unix2dos等 |
archival | 與壓縮有關的命令原始檔,例如:bzip2、gzip等 |
configs | 自帶的一些預設配置檔案 |
console-tools | 與控制檯相關的一些命令,例如:setconsole |
coreutils | 常用的核心命令,例如:cat、rm等 |
editors | 常用的編輯命令,例如:vi、diff等 |
findutils | 用於查詢的命令,例如:find、grep等 |
init | init程式的實現原始檔 |
networking | 與網路相關的命令,例如:telnetl、arp等 |
shell | 與shell相關的實現,例如:ash、msh等 |
util-linux | Linux下常用的命令,主要是與檔案系統相關的,例如:mkfs_ext2等 |
Menuconfig 選項說明
Busybox Settings ---> # BusyBox的通用配置,一般採用預設值即可。
Archival Utilities ---> # 壓縮、解壓縮相關工具。
Coreutils ---> # 最基本的命令,如cat、cp、ls等。
Console Utilities ---> # 控制檯相關命令。
Debian Utilities ---> # Debian作業系統相關命令。
Editors ---> # 編輯工具,如vi、awk、sed等。
Finding Utilities ---> # 查詢工具,如find、grep、xargs。
Init Utilities ---> # BusyBox init相關命令。
Login/Password Management Utilities ---> # 登陸、使用者賬號/密碼等方面的命令。
Linux Ext2 FS Progs ---> # ext2檔案系統的一些工具。
Linux Module Utilities ---> # 載入/解除安裝模組等相關的命令。
Linux System Utilities ---> # 一些系統命令。
Miscellaneous Utilities ---> # 一些不好分類的命令,如crond、crontab。
Networking Utilities ---> # 網路相關的命令和工具。
Print Utilities ---> # print spool服務及相關工具。
Mail Utilities ---> # mail相關命令。
Process Utilities ---> # 程式相關命令,如ps、kill等。
Runit Utilities ---> # runit程式。
Shells ---> # shell程式。
System Logging Utilities ---> # 系統日誌相關工具,如syslogd、klogd。
編譯 BusyBox
-
解壓 Busybox 原始碼後,進入 Busybox 目錄,開啟影像介面配置選單:
make menuconfig
-
進入配置選單後,進行相關配置。我們可以靜態或者動態編譯Busybox,選擇動態編譯,使得Busybox可執行檔案更小,選項開關如下:
[ ] Build BusyBox as a static binary (no shared libs)
-
經過上訴步驟之後,這個時候選擇配置介面的 Exit 退出,儲存剛剛的配置,之後就可以看到在原始碼目錄下多了一個 .config 檔案。.config 配置檔案裡面的內容記錄了我們剛剛選中的功能。如下所示:
CONFIG_PLATFORM_LINUX=y
每一個都是名值對的形式,名稱是一個環境變數,後面的值如果為 Y 代表選中,註釋行代表裁減掉的功能。
-
開始編譯並安裝
make make install
生成的檔案將預設安裝到目錄 _install。
使用 BusyBox 進行除錯
BusyBox 編譯成功後,在 目錄 _install 下可以看到生成的 檔案,我們可以繼續新增檔案,做成一個最小根檔案系統。或是直接操作 Busybox 這個可執行檔案,用法如下:
./BusyBox 命令 [引數]
其中 命令 是編譯 BusyBox 時選中的命令,用法同 Linux 下的命令,只是加上 ./BusyBox 。比如我們在編譯時選中的 flashcp 命令,編譯成功後,我們把 BusyBox 放到開發板中,就可以直接使用新加入的 flashcp 命令了,而不用重新編譯和燒錄根檔案系統到開發板中:
./BusyBox flashcp /tmp/nfs/usr.sqsh4 /dev/mtd7
完善根檔案系統
新增 inittab 檔案
inittab 被 /linuxrc(也就是 busybox)執行時所呼叫而起作用。存放在/etc 目錄下,屬於一個執行時配置檔案,是文字格式的。實際工作的時候 busybox 會(按照一定的格式)解析這個 inittab文字檔案,然後根據解析的內容來決定要怎麼工作。inittab 的格式在 busybox 中定義的。
將 inittab 檔案放到到我們製作的 rootfs 的根目錄下的 /etc/ 目錄下,啟動並且掛載 rootfs 進入了控制檯命令列。當前製作的最小 rootfs 就成功了。典型的 inittab :
#/etc/inittab # 井號是註釋
::sysinit:/etc/init.d/rcS # 系統啟動以後執行 /etc/init.d/rcS 這個指令碼檔案
console::askfirst:-/bin/sh # 將 console 作為控制檯終端,也就是 ttymxc0。
::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/swapoff,也就是關閉交換分割槽。
-
冒號在裡面是分隔符,分隔開各個部分。以行為單位的,行與行之間沒有關聯,每一行的配置項都是由 3 個冒號分隔開的 4 個配置值共同確定的( id : runlevels : action : process )。有些配置值可以空缺,空缺後冒號不能空缺。
-
action 是一個條件/狀態,process 是一個可被執行的程式的 pathname。合起來的意思就是:當滿足 action 的條件時就會執行 process 這個程式:busybox 最終會進入一個死迴圈,在這個死迴圈中去反覆檢查是否滿足各個 action 的條件,如果某個 action 的條件滿足就會去執行對應的 process。
動作 描述 sysinit 在系統初始化的時候 process 才會執行一次。 respawn 當 process 終止以後馬上啟動一個新的 askfirst 和 respawn 類似,在執行 process 之前在控制檯上顯示“Please press Enter to activate this console.”。只要使用者按下“Enter”鍵以後才會執行 process。 wait 告訴 init,要等待相應的程式執行完以後才能繼續執行。 once 僅執行一次,而且不會等待 process 執行完成。 restart 當 init 重啟的時候才會執行 procee。 ctrlaltdel 當按下 ctrl+alt+del 組合鍵才會執行 process。 shutdown 關機的時候執行 process。
- inittab 的解析是在 busybox/init/init.c/init_main 函式中。執行邏輯是:先通過 parse_inittab 函式解析 /etc/inittab(解析的重點是將 inittab 中的各個 action 和 process 解析出來),然後後面先直接執行 sysinit 和 wait 和 once(只執行一遍),然後在 while(1) 死迴圈中去執行 respwan 和 askfirst。
新增登陸系統
-
之前新增了 /bin/hostname 在 /etc/sysconfig/HOSTNAME 檔案中定義了一個 hostname,實際效果是:命令列下 hostname 命令查到的 host 名字正確。但是命令列的提示符是沒有顯示的。這個問題的解決就要靠profile 檔案。將提供的 profile 檔案放入 /etc/ 目錄下即可。新增之後命令列提示符前面顯示:
[@aston210 ]#
-
profile 檔案也是被 busybox(init 程式)自動呼叫的,所以是認名字的。
-
在 intttab 中有一個配置項 ::askfirst:-/bin/sh,這個配置項作用就是當系統啟動後就去執行 /bin/sh,執行這個就會出現命令列。因此我們這樣的安排就會直接進入命令列而不會出現登入介面。我們要出現登入介面,就不能直接執行/bin/sh,而應該執行一個負責出現登入介面並且負責管理使用者名稱和密碼的一個程式,busybox 中也整合了這個程式(就是/bin/login 和/sbin/gettty),因此我們要在 inittab 中用 /bin/login 或者 /sbin/getty 去替代 /bin/sh:
: :askfirst : -/bin/sh # 啟動後按回車不用登陸直接進入命令列 #: : respawn : -/bin/sh # 可去除按回車的步驟。自己進入命令列 : : sysinit : /bin/login # 啟動後進入使用者登陸程式,
-
passwd 檔案中儲存的是使用者的密碼設定,shadow 檔案中儲存的是加密後的密碼。我們直接複製 ubuntu 系統中的/etc/passwd 和/etc/shadow 檔案到當前製作的 rootfs 目錄下,然後再做修改即可。修改方法:只保留 root 那一行,如
root:x:0:0:root:/root:/bin/sh # passwd 檔案,最後是 sh root :tyLxf271Ytqok:0:0:99999:7::: # shadow 檔案:123456 的密文
-
重置密碼
- ubuntu 中,普通使用者登陸後可以使用 su passwd root 給 root 使用者設定密碼。
- busybox 中沒有普通使用者,直接使用 passwd root 給 root 使用者設定密碼。
- 平時有時候我們忘記了自己的作業系統的密碼,怎麼辦?有一種解決方法就是用其他系統( WindowsPE 系統或者 ubuntu 的單使用者模式等···)來引導啟動,啟動後掛載到我們的硬碟上,然後找到 /etc/shadow 檔案,去掉密文密碼後儲存。然後再重啟系統後密碼就沒了。
-
getty 實戰
-
inittab 中最常見的用於登入的程式不是 /bin/login,反而是 /sbin/getty。在 busybox 中這兩個是一樣的,都是 busybox 的符號連結而已,因此不用嚴格區分這兩個。
-
我們可以在 inittab 中用 getty 替換 login 程式來實現同樣的效果。
s3c2410_serial2::respawn:/sbin/getty -L s3c2410..... 115200 vt100
-
新增 rcS 檔案
精簡 rcS 檔案示例
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH # 匯出上面這些環境變數
mount -a # 掛載所有的檔案系統,需存在/etc/fstab 檔案
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug # 這兩行跟/dev 有關
mdev -s
/bin/hostname -F /etc/sysconfig/HOSTNAME # 設定主機名為 HOSTNAME 寫的名字
/etc/init.d/rcS 檔案是 linux 的執行時配置檔案中最重要的一個,其他的一些配置都是由這個檔案引出來的。這個檔案可以很複雜也可很簡單,裡面可以有很多的配置項。可以通過修改 rcS 實現開機自啟動,例如新增:
runlevel=S # 表示將系統設定為單使用者模式
umask 022 # 設定 linux 系統的 umask 值
ifconfig eth0 192.168.1.10 # 設定 IP,預設為 bootcmd 設定的 IP 地址
-
正式產品中的 rcS 是一個引入,不是真正幹活的。真正幹活的/etc/init.d/中的其他指令碼。
-
建立好檔案/etc/init.d/rcS 以後一定要給其可執行許可權!
-
當提示檔案不存在時,可以通過開發板 vi 檢視該檔案,看看是不是結尾多出來了一個 ^M,有的話刪掉即可。這是因為 rcS 檔案在 windows 下建立時,行尾換行符為'\r\n',這個換行符 ubuntu 的 vi 自動進行優化,但是開發板的 vi 卻沒有,所以只能以^M 顯示。
-
啟發:shell 指令碼檔案如果格式不對,執行時可能會被提示檔案不存在。有時候一個應用程式執行時也會提示檔案不存在,問題可能是這個程式所呼叫的一個動態連結庫找不到。
umask 測試
-
umask 是 linux 的一個命令,作用是設定 linux 系統的 umask 值。umask 值決定當前使用者在建立檔案時的預設許可權。
-
測試結果:
- umask 是 022 的時候,預設 touch 建立一個檔案的許可權是 644
- umask 是 044 的時候,預設 touch 建立一個檔案的許可權是 622
- umask 是 444 的時候,預設 touch 建立一個檔案的許可權是 222
-
總結:umask 的規律就是:umask 值和預設建立檔案的許可權值加起來是 666。
PATH 測試
- PATH=xxx:這一行定義了一個變數 PATH,值等於後面的字串。後面用 export 匯出了這個 PATH,那麼 PATH 就變成了一個環境變數。
- 測試結果:我們的 rcS 檔案還沒新增,系統啟動就有了 PATH 中的值?原因在於 busybox 自己用程式碼硬編碼為我們匯出了一些環境變數,其中就有 PATH。因此看不出什麼差別。
runlevel 測試
- runlevel 也是一個 shell 變數,並且被匯出為環境變數。
- 測試結果:runlevel 執行結果一直是 unknown,因為 busybox 並不支援 runlevel 這個特性。
mount 測試
-
mount命令是用來掛載檔案系統的。mount -a 是掛載所有的應該被掛載的檔案系統,在 busybox中 mount -a 時 busybox 會去查詢一個檔案 /etc/fstab 檔案,這個檔案按照一定的格式列出來所有應該被掛載的檔案系統(包括了虛擬檔案系統)
-
測試結果:掛載時全部出錯:
mount: mounting proc on /proc failed: No such file or directory mount: mounting sysfs on /sys failed: No such file or directory mount: mounting tmpfs on /var failed: No such file or directory mount: mounting tmpfs on /tmp failed: No such file or directory mount: mounting tmpfs on /dev failed: No such file or directory
-
原因:根檔案系統中找不到掛載點。所謂掛載點就是我們要將目標檔案系統(當然這裡都是虛擬檔案系統)掛載到當前檔案系統中的某一個目錄中,這個目錄就是掛載點。
-
解決方案:自己在製作的 rootfs 根目錄下建立這些掛載點目錄即可。
mdev 測試
- mdev 是 udev 的嵌入式簡化版本,udev/mdev 是用來配合 linux 驅動工作的一個應用層的軟體,udev/mdev 的工作就是配合 linux 驅動生成相應的 /dev 目錄下的裝置檔案。
- 在 rcS 檔案中沒有啟動 mdev 的時候,/dev 目錄下啟動後是空的;在 rcS 檔案中新增上 mdev 有關的 2 行配置項後,再次啟動系統後發現/dev 目錄下生成了很多的裝置驅動檔案。
- /dev 目錄下的裝置驅動檔案就是 mdev 生成的,這就是 mdev 的效果和意義。
hostname 測試
- hostname 是 linux 中的一個 shell 命令。命令(hostname xxx)執行後可以用來設定當前系統的主機名為 xxx,直接 hostname 不加引數可以顯示當前系統的主機名。
- /bin/hostname -F /etc/sysconfig/HOSTNAME -F 來指定了一個主機名配置檔案(這個檔案一般檔名叫 hostname 或者 HOSTNAME),可以這這個配置檔案裡更改主機名。
- 需要加入 profile 檔案才能在命令列前顯示相關字首。
動態連結庫的拷貝
靜態連結:arm-linux-gcc hello.c -o hello_satic -static //加 -static 命令即可
動態連結:arm-linux-gcc hello.c -o hello_dynamic
實驗結果:靜態編譯連線後生成的 hello_satic 已經可以成功執行。而動態編譯連結程式不能執行。
分析:靜態連結時,把需要的庫檔案都連結到了一起,可以獨立執行,但是體積大(10 倍)
Linux下執行程式時,無論程式是動態編譯還是靜態編譯,都需要一些基本庫的支援。若是根檔案系統中沒有任何庫檔案,直接執行程式將提示找不到可執行檔案,即使該可執行檔案就在當前目錄下。為了完善根檔案系統,我們需要繼續 在 rootfs 中建立 /lib 目錄,並新增必要的庫檔案。在不知道需要哪些庫檔案的情況下,我們可以直接複製 gcc 中的動態庫檔案。步驟如下:
-
找到動態連結庫檔案:從交叉編譯工具鏈資料夾中尋找,可使用 find -name “libm.so”定位到目標目錄。一般安裝的編譯工具鏈目錄下,如:/usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib ( 僅供參考)
-
複製動態連結庫到 roots/lib 目錄下。
cp lib/*so* /rootfs/lib/ -rdf # -rdf:保留符號連結而非實體
-
使用 strip 工具去掉庫中符號資訊:動態連結庫 so 檔案中包含了除錯符號資訊,這些符號資訊在執行時是沒用的(除錯時用的),佔用空間。在傳統的嵌入式系統中 flash 空間是有限的,為了節省空間常常把這些符號資訊去掉。這樣節省空間並且不影響執行。
arm-linux-strip *so* # 執行後從 30 M 縮小到了 3.8 M
最小 rootfs 目錄結構
- dev 目錄。在 linux 中一切皆是檔案,因此一個硬體裝置也被虛擬化成一個裝置檔案來訪問,在 linux 系統中 /dev/xxx 就表示一個硬體裝置
- sys 和 proc 目錄。該目錄在最小 rootfs 中也是,屬於 linux 中的虛擬檔案系統。
目錄 | 說明 | 補充 |
---|---|---|
linuxrc | 最重要 | 必須存在 |
bin | 可執行檔案,最主要的是 busybox | 必須存在 |
sbin | 可執行檔案,連結指向 /bin/busybox | 必須存在 |
usr | 系統使用者所有的一些檔案的存放地,busybox 安裝時預設建立 | 可以刪除 |
etc | 存放配置檔案,被 /linuxrc 所呼叫執行 | 必須存在 |
lib | 存放的是當前作業系統中的動態和靜態連結庫檔案。 | 必須存在 |
dev | 裝置檔案 | 必須存在 |
sys | 虛擬檔案系統,不可省略的,但是隻要建立了空資料夾即可 | 必須存在 |
proc | 虛擬檔案系統,不可省略的,但是隻要建立了空資料夾即可 | 必須存在 |
mnt | 用來掛載 | 可以刪除 |