一、前言
? ? ? ? 在前面的教程中,教了大家如何移植一個LInux的內核并且正確啟動,我們發現Linux內核在啟動后會出現一個錯誤,提示我們沒有找到根文件系統。那么什么是根文件系統呢?之前我們使用Ubuntu編譯了STM32MP157的TF-A,UBOOT,LINUX內核相信大家對Ubuntu已經不陌生了,我們可以看到Ubuntu的路徑都是從“/”開始寫的,然而這個“/”就被我們叫做根,“/”與它下面掛載的文件并稱為根文件系統。可以看到,根文件系統構建了我們系統的整個文件管理系統,我們的所有操作都是建立在根文件系統之上的,所以Linux內核一般與根文件系統一起出現,那么本次教程就來教大家如何為STM32MP157移植一個根文件系統并且正確啟動,如果你準備好了,就讓我們開始吧!
二、誰適合本次教程
? ? ? ? 根文件系統已經處于Linux內核的上層了,本質上是一些較為上層的操作,移植起來也比較簡單,甚至需要我們改動的地方都很少,所以難度是比較低的,至少比移植前面幾個模塊的難度要低。所以如果你能完成前面模塊的移植,那么本次移植肯定是沒問題的。如果你使用的是別的開發板,也可以參考本次教程,上層的操作都大同小異,但是也僅僅只是作為參考,中間肯定有不一樣的地方。
三、資料的準備
? ? ? ? 本次我們依然會使用正點原子的官方資料,下載方式在搭建編譯環境時就講過了,如果還不知道如何下載,可以看下面的文章中的資料下載部分:
STM32MP157交叉編譯環境搭建:[Linux]從零開始的STM32MP157交叉編譯環境配置-CSDN博客
資料下載完成以后如圖所示:
準備好資料以后,就可以進行下一步了。
四、根文件系統的選擇
? ? ? ? 目前主流的根文件系統有兩個,分別是Busybox和Buildroot。我們應該如何選擇這兩種根文件系統呢,下面會分別探討一下這兩種根文件系統的優缺點。首先時Busybox,這是一款比較老的根文件系統,里面整理了常用的工具,缺點也很明顯,許多鏈接庫或者系統文件需要我們自己進行復制,不利于新手,但Busybox可以讓我們更好的理解根文件系統中每個文件夾的作用,畢竟每個文件夾都是自己來構建的嘛!然后是Buildroot,Buildroot中集成了我們常用的模塊,它將Busybot甚至Uboot與Linux內核都集成到了其中。所以可以看出Buildroot的集成度是非常高的,這也為我們編譯省去了非常多不必要的步驟,在本次教程中也會使用Buildroot來進行演示,當然在后面的教程中也會為大家講解Busybox。
五、Buildroot的編譯與掛載
? ? ? ? 與前面幾個模塊一樣,Buildroot是需要我們自己編譯并且掛載的。當然,編譯的第一步我們還是先找源碼,Buildroot的源碼在它的官網可以直接下載到,但是有一些問題,如果現在去官網下載Buildroot的源碼的話,下載下來的源碼是2025年2月份的,如果使用正點原子提供的2019年的gcc編譯器去編譯這個源碼的話,就可能出現一些路徑找不到的問題,這里除非換編譯器,不然編譯肯定是會失敗的,這里我已經替大家測試過了。所以我們這里就使用正點原子提供給我們的源碼。Buildroot的源碼被放在了正點原子資料目錄下的“01、程序源碼\07、Buildroot源碼”目錄下,如圖所示:
這里我們在Ubuntu的用戶目錄下的“Linux”目錄下新建一個名為“BUILDROOT”的文件夾,使用下面的命令即可:
mkdir BUILDROOT
新建完成以后如圖所示:
然后我們將一開始找到的Buildroot的源碼拷貝的這個目錄中,這里不管是使用sftp還是直接復制都可以,將文件傳輸過去就行,完成以后如圖所示:
我們使用下面的命令來解壓這個壓縮包:
tar -xvf buildroot-2020.02.6.tar.bz2
解壓完成以后,得到以下文件夾:
進入這個文件夾中,可以看到以下文件:
這些就是Buildroot的源碼文件,下面我們來配置Buildroot,Buildroot是支持圖形化配置的,所以我們可以直接在Buildroot的源碼目錄下輸入下面的命令來啟動圖形化配置:
make menuconfig
關于圖形化配置,在之前的UBOOT圖像化配置中已經講得很詳細了,這里就不多說了,如果你還不會圖形化配置,或者不知到圖像化配置的原理,可以看下面的文章:
UBOOT圖形化配置及原理講解:[Linux]從零開始的STM32MP157 U-Boot圖形化配置及Kconfig文件講解_kconfig圖形化配置應用于應用層軟件代碼項目中-CSDN博客
下面我們繼續回到正題。?
圖形化配置啟動以后,如圖所示:
下面我們開始配置,首先我們來配置“Target options”:
進入“Target options”后,可以看到以下配置項:
這里我們選擇“Target Architecture (i386) ?---> ”回車進入,進圖后可以看到以下選項:
針對STM32MP157來說我們需要選擇“( ) ARM (little endian) ”,如圖所示:
將選框移動到該位置然后按下回車就可以選中這個選項了,選擇以后,我們界面中就會出現下面這些選項:
這里我們需要對這些選項進行以下配置:
這里選項都是一一對應,大家直接跟著圖上配即可,配置完成以后,如圖所示:
這樣我們“Target options”的配置就完成了。下面我們來配置“Toolchain”位置如圖所示:
“Toolchain”主要用于配置交叉編譯器,進入后,可以看到以下選項:
這里的配置我們只需要修改幾項即可,大家跟著我操作,首先就是“Toolchain type”我們將其配置為“(External toolchain) ?---> ?”配置完成以后如圖所示:
然后將“Toolchain”配置為“(Custom toolchain) ?--->?”,表示使用用戶自己的編譯器,完成后如圖:
隨后的“Toolchain origin”要配置為“(Pre-installed toolchain) ?--->?”:
隨后我們要將“Toolchain path (NEW)?”配置為我們自己交叉編譯器的路徑,這里如果大家之前也是跟著我配的的話,那么路徑就是:
/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf
我們直接填入即可:
完成以后如圖所示:
此后我們還需要將“Toolchain prefix”修改為“$(ARCH)-none-linux-gnueabihf”,如圖:
下方的“External toolchain gcc version?”我們選項“9.x”,“External toolchain kernel headers series”我們選擇“4.20.x”,完成后如圖所示:
然后下方的“External toolchain C library”我們選擇“glibc/eglibc”:
最后我們需要將下方的“Toolchain has SSP support? (NEW)”、“Toolchain has RPC support? (NEW)”、“Toolchain has C++ support?”、“Enable MMU support (NEW)?”都選中,如圖所示:
至此,我們的“Toolchain”就配置完成了。下面我們來配置“System configuration”,位置如圖所示:
進入以后,可以看到以下選項:
同樣的,這里只需要修改幾個選項即可,首先是“System hostname”這是我們平臺的名字,大家可以自行設置:
“System banner”表示系統的歡迎語,大家自行設置即可:
“Init system”我們這里選擇“Busybox”:
“/dev management”我們選擇“Dynamic using devtmpfs + mdev”:
這里我們選中“Enable root login with password”表示使能root用戶的登錄密碼,在下方我們可以設置root用戶的登錄密碼:
當然,這里的密碼會在我們做Linux驅動開始時取消掉,不然我們每次進入系統都需要輸入密碼,非常不利于開發。這里作為測試,所以使能了密碼。
至此,“System configuration”配置就完成了,下面我們來配置“Filesystem images”,在如圖所示位置:
進入以后可以看到以下選項:
這里我們選中“ext2/3/4 root filesystem”,然后在下方新彈出的“ext2/3/4 variant”選項中選擇“ext4”:
然后我們將下方的“exact size”改為1G:
至此“Filesystem images”配置就完成了。下面我們來配置“Target packages”,在如圖所示位置:
進入以后,可以看到以下選項:
我們往下滑找到“System tools”選項并且進入,在如圖所示位置:
進入以后,可以看到以下選項:
我們往下滑找到“kmod”并且選中:
因為buildroot在編譯時會在一些國外的網站下載東西,因為網絡問題可能會下載失敗,所以這里我們需要將下載連接配置為國內鏡像,這里我們進入“Build options”選項,在如圖所示位置:
進入以后,可以看到以下選項:
我們進入“Mirrors and Download locations”選項,可以看到以下界面:
我們進行下面的修改:
Backup download site :http://sources.buildroot.net
Kernel.org mirror :https://mirror.bjtu.edu.cn/kernel/
GNU Software mirror :http://mirrors.nju.edu.cn/gnu/
LuaRocks mirror :https://luarocks.cn
CPAN mirror (Perl packages) :http://mirrors.nju.edu.cn/CPAN/
修改完成以后,如圖所示:
至此,我們所有的配置都已經完成,我們將配置文件保存到“./configs/stm32mp1_atk_defconfig”目錄中,作為默認配置,后面直接加載即可:
保存完成以后,我們使用下方的命令加載配置文件:
make stm32mp1_atk_defconfig
加載完成以后,可以看到,相關配置已經被寫到了“.config”文件中:
我們使用下面的命令,這里的編譯線程數大家根據自己的情況寫即可:
make -j16
編譯完成以后,如圖所示:
這里我們進入Buildroot項目文件夾的“output/image”文件夾中,可以看到以下文件:
在“rootfs.tar”內就是我們編譯的根文件系統了,下面來教大家如何掛載根文件系統。
這里我們要使用nfs來掛載根文件系統,所以這里大家需要確保自己的網絡和nfs配置都沒有問題,如果你還不會配置Uboot的網絡和nfs可以看下面的文章:
UBOOT網絡配置:[Linux]從零開始的STM32MP157 U-Boot網絡命令講解及相關配置_stm32mp157 聯網-CSDN博客
這里我們在開發板一側是可以ping到ubuntu的:
現在我們首先在nfs目錄中新建一個名為“rootfs”的文件夾用來存放我們的根文件系統:
這里我們將剛才編譯出來的“rootfs.tar”復制到新建的“rootfs”中:
然后使用下方的命令解壓這個壓縮包:
tar -xvf rootfs.tar
解壓后我們可以看到以下文件夾,這些文件夾都是Linux的根文件,想必大家已經非常熟悉了:
最后我們使用下面的命令將原本的壓縮包刪掉:
rm -rf ./rootfs.tar
這里我們還需要修改以下nfs的配置文件,使用下面的命令打開配置文件:
sudo nano /etc/default/nfs-kernel-server
打開后可以看到以下內容:
我們在最后一行加上下面的內容:
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
修改完以后如圖所示:?
最后我們保存退出即可。
修改完配置文件以后,我們使用下面的命令重新啟動軟件:
sudo /etc/init.d/nfs-kernel-server restart
這里顯示ok以后,nfs的配置就修改完成了:
現在在開發板端,我們需要修改一下bootargs環境變量,使用下面的命令:
setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.100:/home/chulingxiao/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.106:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off
這里大家注意,這是一行命令,不要換行。大家使用時,需要修改幾個地方,下面一一來講,首先是“nfsroot=192.168.1.100:/home/chulingxiao/linux/nfs/rootfs”這里大家需要把這里的IP地址修改為自己Ubuntu的地址。后面的路徑大家寫自己的rootfs文件夾的路徑。然后是“ip=192.168.1.106:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off”這里有三個地址,按照從前到后的順序是“開發板的IP地址”,“Ubuntu的IP地址”,“網關的IP地址”,大家根據自己的情況配置即可。
輸入命令后,使用“saveenv”將環境變量保存到EMMC中:
完成以后,我們使用“boot”命令加載內核和根文件系統:
等內核啟動以后,根文件系統就掛載完成了,并且出現了登錄提示:
這里用戶名我們使用root,密碼就是我們設置的密碼:
登錄完成以后,可以看到前面變成了“#”,我們可以使用cd命令切換到根目錄:
這里可以看到,我們的根文件系統已經啟動完成了,雖然前面被提示一些目錄找不到,但是問題不大,至少根文件系統啟動成功,后面我們再來慢慢完善這個系統吧!
六、結語
? ? ? ? 在本次教程中,我們編譯并且成功啟動了buildroot根文件系統,這也意味著我們移植了一個完整可用的Linux系統,在后續,我們會在此基礎上進行完善以及進行LInux驅動開發,那么最后,感謝大家的觀看!