天天看點

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

文章目錄

1. 根檔案系統布局

嵌入式 Linux 根檔案系統布局,建議還是按照FHS标準來安排,事實上大多數嵌入式Linux都是這樣做的。但是,嵌入式系統可能并不需要桌面/伺服器那樣龐大系統的全部目錄,可以酌情對系統進行精簡,以簡化Linux的使用。如嵌入式Linux檔案系統中通常不會放置核心源碼,因而存的 常不會放置核心源碼,因而存的 常不會放置核心源碼,因而存放源碼的 /usr/src目錄是不必要的, 甚至連頭檔案也不需要,即/usr/include目錄也不必要;但是 /bin、/dev 、/etc、/lib 、/proc 、/sbin、/usr幾個目錄是不可或缺的。

是以,允許嵌入式 Linux 對系統目錄結構進行精簡,以适應具體用場合的需求,一個典型的嵌入式Linux根檔案系統目錄如下所示:

典型嵌入式Linux根檔案系統目錄

目錄

内容

bin

系統指令和工具

dev

系統裝置檔案

etc

系統初始化腳本和配置檔案

lib

系統運作庫檔案

proc

proc檔案系統

sbin

系統管理者指令和工具

sys

sysfs檔案系統

tmp

臨時檔案

usr

使用者指令和工具,下分usr/bin和usr/sbin目錄

var

系統運作産生的可變資料

要建構一個可用的Linux根檔案系統,需要的二進制和庫都不少,完全從零開始也是不現實的,推薦參考其它現有可用的檔案系統,在原基礎上按需修改;或者使用檔案系統制作工具如 BusyBox 來實作檔案系統的生成。

2. 使用BusyBox生成二進制工具

2-1. 擷取BusyBox源碼

Busybox的官方源碼下載下傳路徑為:https://busybox.net/downloads/。

目前最新版本為busybox-1.29.3.tar.bz2。

2-2. 配置BusyBox

解壓源碼,進入根目錄

$ tar jxvf busybox-1.29.3.tar.bz2

$ cd busybox-1.29.3/

首先,執行

$ make menuconfig

進入圖形化配置界面

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

2-2-1. 選擇編譯靜态庫

進入

Settings --->

使用空格鍵選擇編譯靜态庫

--- Build Options

[*] Build static binary (no shared libs)

如圖:

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

2-2-2. 選擇交叉編譯工具鍊

Settings --->

設定項下,填寫交叉編譯工具鍊字首

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

2-2-3. 選擇安裝目錄

Settings --->

設定項下,找到

--- Installation Options ("make install" behavior)

What kind of applet links to install (as soft-links) --->

(./_install) Destination path for 'make install' (NEW)

預設為目前目錄下目錄,這裡我使用預設_install目錄

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

2-2-4. 編譯安裝

退出儲存後,執行編譯

$ make

大概幾分鐘後編譯完成,執行

$ make install

很快就會安裝完成

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

進入_install目錄,檢視生成的檔案

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

建立一個目錄用來存放制作的根檔案系統,可以命名為rootfs。将利用BusyBox生成的二進制檔案及目錄,即_install目錄下的所有檔案及目錄複制到rootfs目錄下。

3. 建構根檔案系統

使用BusyBox編譯後,僅有 bin、sbin、usr這 3個目錄和軟連結linuxrc,目錄裡都是二進制指令工具,這還不足以構成 一個可用的根檔案系統,必須進行其它完善工作,才能建構一個可用的根檔案系統。

3-1. 完善目錄結構

根據典型嵌入式Linux根檔案系統目錄,在rootfs目錄中建立其他目錄

$ mkdir dev etc lib proc sys tmp var

3-2. 添加C運作庫檔案

庫檔案可直接從交叉工具鍊擷取,一般在工具鍊的libc/lib/目錄下。我這裡是在ubuntu下安裝的Linaro的交叉工具鍊

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

庫檔案是在/usr/arm-linux-gnueabihf/lib/目錄下,拷貝動态連結庫檔案到新制作的根檔案系統根目錄下/lib目錄裡

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

這裡隻是拷貝動态連結庫。一般開發程式使用動态編譯需要闆子上動态庫的支援才能運作,是以拷貝動态庫。而靜态庫一般在靜态編譯的時候用到,由于交叉編譯的工作放在了PC上是以闆子上不需要靜态庫,是以沒有必要拷貝,這樣還可以減小根檔案系統的體積。

一般使用gcc編譯後的可執行檔案、目标檔案和動态庫都帶有調試資訊和符号資訊,這些在調試的時候用到,但是卻增大了檔案的大小。通常在PC上調試,或者調試時使用這些帶有調試資訊和符号資訊的庫檔案,程式釋出後使用去掉這些資訊的庫檔案,可以大大縮小根檔案系統的體積。這裡我們去掉這些資訊,方法是使用strip工具:

$ arm-linux-gnueabihf-strip ./*

3-3. 添加初始化配置腳本

初始化配置腳本放在在/etc目錄下,用于系統啟動所需的初始化配置腳本。BusyBox提供了一些初始化範例腳本,在examples/bootfloppy/etc/目錄下。将這些配置檔案複制到 ”目錄下。将這些配置檔案複制到 ”目錄下。将這些配置檔案複制到新制作的根檔案系統etc目錄下

cp -ra ../busybox/busybox-1.29.3/examples/bootfloppy/etc/* etc/

添加後如圖所示:

嵌入式linux根檔案系統ubifs,制作嵌入式Linux根檔案系統

3-3-1. 修改/etc/inittab檔案

/etc/inittab檔案是init程序解析的配置檔案,通過這個配置檔案決定執行哪個程序,何時執行。

将檔案修改為

# 系統啟動時

::sysinit:/etc/init.d/rcS

# 系統啟動按下Enter鍵時

::askfirst:-/bin/sh

# 按下Ctrl+Alt+Del鍵時

::ctrlaltdel:/sbin/reboot

# 系統關機時

::shutdown:/sbin/swapoff -a

::shutdown:/bin/umount -a -r

# 系統重新開機時

::restart:/sbin/init

以上内容定義了系統啟動時,關機時,重新開機時,按下Ctrl+Alt+Del鍵時執行的程序。

3-3-2. 修改/etc/init.d/rcS檔案

#! /bin/sh

# 挂載 /etc/fstab 中定義的所有檔案系統

/bin/mount -a

# 挂載虛拟的devpts檔案系統用于用于僞終端裝置

/bin/mkdir -p /dev/pts

/bin/mount -t devpts devpts /dev/pts

# 使用mdev動态管理u盤和滑鼠等熱插拔裝置

/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug

# 掃描并建立節點

/sbin/mdev -s

3-3-3. 修改/etc/fstab檔案

/etc/fstab檔案存放的是檔案系統資訊。在系統啟動後執行/etc/init.d/rcS檔案裡/bin/mount -a指令時,自動挂載這些檔案系統。

内容如下

# proc /proc proc defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs /tmp tmpfs defaults 0 0

tmpfs /dev tmpfs defaults 0 0

注:這裡我們挂載的檔案系統有三個proc、sysfs和tmpfs,在核心中proc和sysfs預設都支援,而tmpfs是沒有支援的,我們需要添加tmpfs的支援。

3-3-4. 修改/etc/profile檔案

/etc/profile檔案作用是設定環境變量,每個使用者登入時都會運作它。

将檔案内容修改為

# 主機名

export HOSTNAME=zyz

# 使用者名

export USER=root

# 使用者目錄

export HOME=/root

# 終端預設提示符

export PS1="[[email protected]$HOSTNAME:$PWD]# "

# 環境變量

export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# 動态庫路徑

export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

因為指定了root使用者的家目錄為/root,是以需要建立該目錄,否則執行cd ~時會失敗

$ mkdir root

登入系統後效果為

...

Please press Enter to activate this console.

[[email protected]:/]#

[[email protected]:/]# cd ~

[[email protected]:/root]#

[[email protected]:/root]# echo $PATH

/bin:/sbin:/usr/bin:/usr/sbin

至此,根檔案系統就基本建構好了。

4. 制作根檔案系統鏡像

4-1. 根檔案系統類型

如果檔案系統已經布局完成, 則可以發到目标中了。通常會制作一個鏡像然後通過某種方式固化到目标系統中,具體采用什麼樣的形釋出需要根據資源狀況、核心情況和系統需求等方面進行裁決:

硬體方面,至少需要考慮主存儲媒體的類型和大小如Flash是NOR Flash還是NAND Flash,RAM的大小等。

核心方面, 則需考慮所裁剪後的支援哪些檔案系統采用種最合适, 能滿足性、速度等要求。

系統需求方面,要考慮運作速度、是否可寫壓縮等因素。

常見的可用于根檔案系統類型有ramdisk 、cramfs、jffs2 、yaffs/yaffs2和 ubifs等,各類型的特性如表所列。

類型

媒體

是否壓縮

是否可寫

掉電儲存

存在于RAM中

Ramdisk

cramfs

-

jffs2

NOR Flash

yaffs/yaffs2

NAND Flash

ubifs

NAND Flash

盡管檔案系統固件以某一種檔案系統的鏡像釋出,但是整個檔案系統實際上還是并存多種邏輯檔案系統的。例如,一個系統根檔案系統以ubifs挂載,但是/dev目錄卻是以tmpfs挂載的、/sys目錄挂載的是sysfs檔案系統。

現在,似乎ubifs是一種趨勢。

4-2. 制作UBIFS根檔案系統鏡像

Linux下制作UBIFS的指令有兩個,mkfs.ubifs和ubinize。

mkfs.ubifs,将一個目錄制作為UBIFS檔案系統。使用範例

$ mkfs.ubifs -m 2048 -e 128KiB -c 4096 -r ./rootfs -o rootfs.ubifs

其中

-r, -d, --root=DIR build file system from directory DIR(目錄)

-m, --min-io-size=SIZE minimum I/O unit size(最小輸入輸出單元大小)

-e, --leb-size=SIZE logical erase block size(邏輯擦除塊大小)

-c, --max-leb-cnt=COUNT maximum logical erase block count(最大邏輯擦除塊數目)

-o, --output=FILE output to FILE(輸出檔案)

是以制作ubifs鏡像檔案,需要知道3個關鍵參數,即最小輸入輸出單元大小,邏輯擦除塊大小,最大邏輯擦除塊數目,其中最大邏輯擦除塊數目可由Flash分區大小和邏輯擦除塊大小計算出來,這些資訊可以通過u-boot指令檢視

=> mtdparts default

=> ubi part rootfs

ubinize,将mkfs.ubifs制作的UBIFS檔案系統制作成含有卷标的可以直接燒寫在Flash上的鏡像。使用範例

$ ubinize -m 2048 -p 128KiB ubinize.cfg -o rootfs_ubifs.img

其中

-o, --output=output file name(輸出檔案)

-p, --peb-size=size of the physical eraseblock of the flash(實體擦除塊大小)

this UBI image is created for in bytes,

kilobytes (KiB), or megabytes (MiB)

(mandatory parameter)

-m, --min-io-size=minimum input/output unit size of the flash

in bytes

這裡需要兩個參數實體擦除塊大小和最小輸入輸出單元大小。

ubinize.cfg是配置檔案,内容如下

[ubifs]

mode=ubi

image=rootfs.ubifs

vol_id=0

vol_size=1024MiB

vol_type=dynamic

vol_name=rootfs

vol_flags=autoresize

說明

[ubifs]

mode=ubi

image=rootfs.ubifs # mkfs.ubi生成的源鏡像

vol_id=0 # 卷号

vol_size=1024MiB # 卷大小,一般要設定的比分區大,防止有壞塊

vol_type=dynamic # 卷類型,動态卷

vol_name=rootfs # 卷名,rootfs

vol_flags=autoresize # 自動大小

至此,根檔案系統就制作好了,rootfs_ubifs.img可以燒寫到flash使用。