(一)準備工作
- Ubuntu 16.04系統
- linux-3.5內核:linux-3.5-20190929
- 交叉編譯工具arm-linux-gcc-4.5.1-v6-vfp-20120301.rar
- busybox源碼包:busybox-1.21.1.rar
(二)工具介紹
(1)交叉編譯器
這個其實之前就已經講過了,不懂的參考我的另一篇文章linux安裝交叉編譯環境
交叉編譯器和本地編譯器是相對應的概念,在嵌入式開發的時候,由于目標板的資源有限,我們一般在電腦上編譯好在目標板上運行的程序,然后下到板子里,這就需要用到交叉編譯器的概念。具體的
(2)NFS文系統
NFS(NetWork Filesystem System)文件系統是基于 網絡傳輸文件,在嵌入式領域應用十分廣泛,可以用于主機和嵌入式設備之間無縫傳輸文件。
NFS服務是基于客戶端和服務器模式,NFS服務器是提供輸出文件(共享文件)的計算機。NFS客戶端是訪問輸出文件的計算機,它可以將輸出目錄掛載到自己系統中的某個目錄中,然后像訪問本地文件一樣去訪問NFS服務器中的輸出文件。
關于NFS的具體教程可以參考NFS網絡文件系統詳解,不過本節我們直接使用,并不影響我們操作。
(3)busybox的作用
Busybox是一個集成了上百個常用linux命令和工具的軟件,是一個遵循GPL協議開源項目。Busybox將眾多的UNIX命令集合進一個很小的可執行程序中,與相應的GNU工具相比,所能提供的選項比較少,但是也足夠一般的應用了,Busybox主要用于嵌入式系統,是一個“萬能工具”,可使用在數字電視、mp3、音響、小型服務器等嵌入式產品中。
在使用Busybox創建根文件系統的時候,只需要在/dev目錄下創建必要的設備節點,在/etc目錄下增加一些配置文件即可,當然,如果Busybox使用動態鏈接,那么還需要再/lib目錄下包含庫文件。
(三)制作步驟
(1)安裝交叉編譯器
參考linux安裝交叉編譯環境
(2)搭建NFS服務器
- 安裝nfs服務
$ sudo apt-get install nfs-kernel-server nfs-common
- 修改配置文件
$ sudo vim /etc/exports
注:“exports”文件用于配置NFS服務器中輸出的共享目錄
修改內容如下:
/driver/rootfs *(rw,sync,no_root_squash,no_subtree_check)
注:/root/rootfs為與nfs服務客戶端共享的目錄,可自行創建,這個路徑必須為絕對路徑。
*:允許所有的網段訪問,也可以使用具體的IP
192.168.1.* 指定網段,在該網段中的用戶可以掛載
ro : 只讀
rw:掛接此目錄的客戶端對該共享目錄具有讀寫權限
sync:資料同步寫入內存和硬盤
no_root_squash:root用戶具有對根目錄的完全管理訪問權限。
no_subtree_check:不檢查父目錄的權限
3.重啟nfs服務和rpcbind 服務
$ sudo /etc/init.d/nfs-kernel-server restart
$ sudo /etc/init.d/rpcbind restart
(3)NFS服務的測試
1.檢查客戶端和服務端的網絡是否連通(ping命令)
ping 服務主機IP
//可以使用windows 的命令行ping你的虛擬機
//有另一臺虛擬機的可以使用別的虛擬機
2.查看服務端的共享目錄
showmount -e 服務主機IP
//虛擬機linux操作
3.將與nfs服務客戶端共享的目錄掛載到本地
mount -t nfs -o nolock 服務主機IP:目標機的共享目留 /mnt
//虛擬機linux操作
注:/mnt 指定將共享目錄掛載的路徑, -t nfs 指定掛在協議是那臺ip地址的主機,mount nfs時,默認選項包括文件鎖,依賴于portmap提供的動態端口分配功能,因此需要解鎖,因此一般直接在指令中直接加上-o nolock。
4.通過訪問/mnt即可訪問共享目錄的內容
ls /mnt
//虛擬機linux操作
5.取消掛載
umount /mnt
注:/mnt 指定將共享目錄掛載的路徑,要和掛載時的路徑相同。
(四)busybox安裝
-
在Ubuntu系統根目錄新建driver目錄
-
將busybox-1.21.1.rar在windows解壓后,復值到虛擬機的driver目錄下
-
對busybox-1.21.1.tar.bz2進行指令解壓
tar -xvf busybox-1.21.1.tar.bz2
- 配置 BusyBox
a) cd busybox-1.21.1.
b) apt-get install libncurses5-dev
注:ubuntu系統缺ncurses devel(提供字符終端處理庫),下載安裝即可
c) make menuconfig
d) 設置共享庫
通過鍵盤的左右鍵選擇select、Exit、help,之后通過enter確定選擇,進行界面的切換。
Busybox Settings —>Build Options —>[*] Build shared libbusybox
按空格選中這個
e) 指定交叉編譯鏈(注意 arm-linux-后面不要有空格)
Busybox Settings —>Build Options —>() Cross Compiler prefix (NEW)
f) 設置安裝路徑(路徑指定為絕對路徑,為安裝生成的根文件系統,目錄層次不要太深,方便之后使用)
Busybox Settings —>
Installation Options (“make install” behavior) —>
(./install) BusyBox installation prefix(NEW)
g) 添加模塊指令
5. 編譯安裝并檢測
# make && make install
# file bin/busybox
通過編譯和安裝,會在/driver/目錄下生成一個相應的rootfs目錄,改目錄下有bin、linuxrc、sbin、usr四個目錄。
6.完善動態鏈接庫
前面操作中busybox設置的是動態鏈接庫,編譯器采用的是arm-linux-gcc,找到安裝arm-linux-gcc的安裝路徑:
root@linux:/driver/rootfs# which arm-linux-gcc
/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-gcc
上面是我的路徑,這個就是要復制出來的動態庫的路徑,而在linux系統下,不同的目錄有著不同的存儲作用,先模仿ubuntu系統,在rootfs 下面新建需要的目錄:
root@linux:/driver/rootfs# mkdir dev ./etc/init.d home proc sys root opt tmp var lib -p
root@linux:/driver/rootfs# cp -rf /opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/lib/*.so* ./lib
(五)構建根文件系統
上面介紹了如何安裝Busbybox,建立了bin、linuxrc、sbin、usr等目錄,最小根文件系統的大部分目錄已經建好,現在開始我們制作根文件系統。
1.構建etc目錄
etc/主要是存放系統的配置文件,內核在啟動和運行過程中需要讀取這些配置文件。之前學習進程章節中知道init的進程號為1,是所有進程的父進程,內核初始化完畢之后,init程序開始運行。其他軟件也同時開始運行。init程序通過/etc/inittab文件進行配置、創建其他子進程,比如調用腳本文件配置IP地址、掛接其他文件系統,最后啟動shell等。etc目錄下的內容取決于要運行的程序,本節只需要創建3個文件:etc/inittab、etc/init.d/rcS、etc/fstab。
(1) 配置inittab文件
etc/inittab屬于一個運行時配置文件,實際工作的時候 busybox 會解析這個 inittab 文本文件,然后根據解析的內容來決定所要進行的工作,inittab 的格式在 busybox 中定義。
root@linux:/driver/rootfs# cp /driver/busybox-1.21.1/examples/inittab /driver/rootfs/etc/
root@linux:/driver/rootfs# vim /driver/rootfs/etc/inittab
注釋或刪除里面的內容,只保留以下4行:
::sysinit:/etc/init.d/rcS //是init進程啟動的第一個子進程,它是一個腳本
console::askfirst:-/bin/sh //啟動shell,以/dev/console作為控制臺
::ctrlaltdel:/sbin/reboot //當按下 Ctrl+Alt+Delete 組合鍵時, init重啟執行程序
::shutdown:/bin/umount -a -r
關機時運行 umount 命令卸載所有的文件系統,如果卸載失敗,試圖以只讀方式重新掛載
(2) 配置fstab文件
執行mount –a時掛接/etc/fstab指定的文件系統,linux下的etc目錄是用來存放系統配置信息以及軟件安裝配置信息,相當于windows下的注冊表
root@linux:/driver/rootfs# cp /etc/fstab /driver/rootfs/etc/
修改內容如下:
# device mount-point type options dump fsck order proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0 tmpfs /dev tmpfs defaults 0 0
device:要掛載的設備
注: tmpfs 是一個臨時文件系統,駐留于你的交換分區或是內存中(取決于你的使用情況)。使用它可以高文件訪問速度,并能保證重啟時會自動清除這些文件。
mount point :設備掛載目錄,需要掛載的文件系統的掛載點
type :要掛載設備或是分區的文件系統類型
options:掛載參數(noauto,auto、user、exec、ro、rw)對于大多數系統使用”defaults”就可以
常用參數:
auto:執行mount –a時自動掛載
noauto:執行mount –a時不掛載
user:允許普通用戶掛載設備
nouser:只允許root用戶掛載設備
exec:允許掛載設備上的程序
Ro:以只讀方式掛載文件系統
rw:以只寫方式掛載文件系統
sync:修改文件時,會自動寫入設備
default:rw、exec、auto、nouser、async的組合
dump:是否提供備份功能,0為不備份,1為要備份
pass:是否開機時對文件系統進行檢查,該字段被fsck命令用來決定在啟動時需要被掃描的文件系統的順序,根文件系統”/”對應該字段的值應該為1,其他文件系統應該為2。若該文件系統無需在啟動時掃描,則設置該字段為0
(3) 配置rcS文件(此文件存放在rootfs下的etc目錄中的init.d目錄下)
rcS為腳本文件,在init配置文件中定義了此為第一個要執行的程序,那就最先執行。可以在此腳本中添加自動執行的命令,內容如下:
#!/bin/sh /bin/mount -a mkdir -p /dev/pts //將文件 /etc/fstab 中指明的文件掛載到對應的掛載點mount -t devpts devpts /dev/ptsecho /sbin/mdev > /proc/sys/kernel/hotplug //熱插拔事件時產生設備節點的支持mdev -s //在/dev目錄下生成內核支持的所有設備的結點/bin/hostname ubuntu //Ubuntu為主機名,自己定義
(4) 配置profile文件
inittab中執行了這樣一個語句“::respawn:-/bin/sh”。啟動/bin/sh程序時會啟動ash的配置信息,而它就是/etc/profile,sh會把profile的所有配置全部都運行一遍,因此用戶可以把自己的啟動程序放在這里。配置內容如下:
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]# '
PATH=$PATH
HOSTNAME=`/bin/hostname` #不要少了“`”這個符號
export USER LOGNAME PS1 PATH
注:這個文件是添加環境變量,以實現控制臺終端命令提示符號模板功能,這些命令包含用戶\u,用戶名配置需要etc/group 和etc/passwd兩個文件,可直接從虛擬機的 Linux 系統的 /etc 目錄中復制這兩個文件到自己開發板根文件系統 etc 目錄。
root@linux:/driver/rootfs# cp /etc/group /etc/passwd /driver/rootfs/etc/
(5) 創建控制臺設備文件和萬能垃圾桶
兩個設備文件在內核掛載完文件系統后,系統會利用mdev自動創建,可是在此之前,即在內核掛載文件系統之前。init進程會用到這兩個設備文件。如果沒有這兩個設備文件會提示如下一些信息
root@linux:/driver/rootfs# ls -l /dev/console /dev/null
crw------- 1 root root 5, 1 4月 8 11:51 /dev/console
crw-rw-rw- 1 root root 1, 3 4月 8 11:51 /dev/null
root@linux:/driver/rootfs# mknod dev/console c 5 1
root@linux:/driver/rootfs# mknod dev/null c 1 3
注:/dev/console創建的文件是字符設備(c),主設備號是5,次設備號是1,只能用mknod命令創建,其作用是通過串口向內核傳送命令的平臺;同理/dev/null,/dev/null看作"黑洞",等價于一個只寫文件,所有寫入內容都會永遠丟失。
(6) 修改配置文件權限
root@linux:/driver/rootfs/etc# pwd
/driver/rootfs/etc
root@linux:/driver/rootfs/etc# ls
fstab group init.d inittab passwd profile
root@linux:/driver/rootfs/etc# ls ./init.d/
rcS
root@linux:/driver/rootfs/etc# chmod +x fstab inittab ./init.d/rcS
(7) NFS文件系統掛接
由于前面的操作已經在系統安裝時已經安裝 NFS 服務器,所以只需要配置和啟動服務即可編輯/etc/exports 文件加入允許其它計算機訪問的目錄和訪問權限(注意是Ubuntu系統下的etc 目錄)。
root@linux:/driver/rootfs/etc# vim /etc/exports
輸入以下內容:
/driver/rootfs/ *(rw,sync,no_root_squash,no_subtree_check)
注意:目錄與 IP 之間用<Tab>鍵
(8) 關 linux 防火墻
a) 檢查防火墻的狀態
root@linux:/driver/rootfs/etc# ufw status
若狀態為不活躍,證明防火墻已經關閉,否則執行:ufw disable
到目前為止跟文件系統已經制作成功。
(六)下載測試
我們下載到tiny4412開發板測試一下:
在下載之前還要設置IP地址:
(1) windows靜態ip設置
(2)關閉windows防火墻
(3)虛擬機的網絡設置
虛擬機工具欄–>編輯–>虛擬網絡編輯器
虛擬機工具欄–>編輯
(4)配置Ubuntu ip
root@linux:~# ifconfig ens33 192.168.1.2
root@linux:~# /etc/init.d/networking restart
(5)鏈接串口,進入uboot交互模式,設置啟動參數
在終端輸入
set bootargs 'noinitrd root=/dev/nfs nfsroot=192.168.1.2:/driver/rootfs ip=192.168.1.5:192.168.1.2:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0 lcd=S70'
注意:此操作為一行指令,不要有換行,可以放到文本中取消換行
NFS文件夾具體的路徑
nfsroot=192.168.1.2:/driver/rootfs ip=192.168.1.5:192.168.1.2:192.168.1.1:255.255.255.0::eth0:off
格式說明:
nfsroot=虛擬機Linux系統IP:根文件系統絕對路徑 ip=開發板IP:虛擬機Linux系統IP:網關:子網掩碼::開發板的網卡設備名(一般是eth0,不是虛擬機):off
保存:
save