1.概述
2.開發(fā)環(huán)境概述
2.1 安裝虛擬機(jī)環(huán)境
2.2 樹莓派開發(fā)環(huán)境搭建
3.交叉編譯工具的安裝與uboot的編譯
3.1 安裝arm 64位交叉編譯環(huán)境
3.2 編譯樹莓派上的uboot
3.3 將u-boot放到樹莓派上運(yùn)行
4.樹莓派4b上的Linux編譯和下載
4.1 編譯樹莓派Linux源代碼
4.2 將編譯好的Linux固件運(yùn)行
5.根文件使用
5.1 uboot中設(shè)置啟動(dòng)項(xiàng)
5.2 插入SD卡掛在到虛擬機(jī)上
5.3 修改文件腳本
6.小結(jié)
1.概述
在這篇文章中,將會(huì)通過樹莓派4的Linux的啟動(dòng)過程,描述如何進(jìn)行嵌入式Linux系統(tǒng)開發(fā)的思路。通過樹莓派4B的啟動(dòng)流程,看到一個(gè)Linux啟動(dòng)過程,同時(shí),通過一步一步搭建一個(gè)完整的樹莓派嵌入式Linux開發(fā)環(huán)境,來指導(dǎo)分析各部分的開發(fā)過程。
通過對(duì)本文的閱讀,可以掌握一些嵌入式Linux開發(fā)和環(huán)境搭建的方法,也能夠?qū)漭?的運(yùn)行流程以及Linux的運(yùn)行流程有一個(gè)大致的了解,從romboot--》uboot--》kernel--》rootfs整個(gè)運(yùn)行流程有了比較清楚的了解后,再去學(xué)習(xí)linux以及嵌入式底層,將會(huì)更加的清晰。
2.開發(fā)環(huán)境概述
嵌入式軟件是獨(dú)特的,它需要利用PC機(jī)編譯嵌入式平臺(tái)可以運(yùn)行的機(jī)器碼,這樣就需要借助交叉編譯工具鏈進(jìn)行。在進(jìn)行Linux的開發(fā)工作時(shí),都會(huì)利用宿主機(jī)進(jìn)行交叉編譯后,將生成的目標(biāo)代碼下載到機(jī)器上運(yùn)行。
一般來說,開發(fā)板和PC的連接渠道是串口和網(wǎng)線,UART可以看到基本的調(diào)試信息,而網(wǎng)線則可以用來將板子和電腦進(jìn)行文件傳輸。
串口連接如下:
網(wǎng)線的連接一般可以將樹莓派和PC都在同一個(gè)網(wǎng)段下。
當(dāng)在同一個(gè)網(wǎng)段內(nèi)進(jìn)行開發(fā)時(shí),比較的方便。做嵌入式Linux開發(fā),使用Linux比較方便。由于大部分學(xué)習(xí)和工作都是在windows下,所以這里可以在Ubuntu下裝一個(gè)虛擬機(jī)進(jìn)行開發(fā)工作。
2.1 安裝虛擬機(jī)環(huán)境
在windows上的虛擬機(jī)環(huán)境可以安裝VMware Workstation 16 Player或者Oracle VM VirtualBox。
2.1.1 鏡像下載
比如VMware Workstation 16 Player這個(gè)軟件,然后從ubuntu的官方下載特定版本。
可以從國內(nèi)鏡像下載,這樣比較快。
選擇特定的版本進(jìn)行安裝
下一步開始安裝ubuntu20.04
然后設(shè)置用戶名和密碼
選擇虛擬機(jī)硬盤空間的大小,為了方便使用,這里設(shè)置40G空間。
接著點(diǎn)擊完成開始安裝。
等一段時(shí)間后,會(huì)進(jìn)入自動(dòng)安裝的界面,全程無需干預(yù)。
完成安裝后,會(huì)自動(dòng)啟動(dòng)。
2.1.2 必要軟件包的安裝
下面列出了需要安裝的軟件包
gitsudo apt install git用于代碼管理,代碼下載
net-toolssudo apt install net-tools提供ifconfig等功能
vimsudo apt install vim文本編輯工具
tftpsudo apt install tftpd-hpa可以通過tftp與樹莓派之間傳輸文件
nfssudo apt install nfs-kernel-server可以提供網(wǎng)絡(luò)共享文件
軟件名稱安裝命令說明
git
首先安裝git
sudo apt install git
為了管理工程,首先需要?jiǎng)?chuàng)建一個(gè)Github的賬號(hào),然后配置git的用戶名和密碼。
git config --global user.name “YOUR_FIRST_NAME YOUR_LAST_NAME” git config --global user.email “YOUR_GIT_ASSOCIATED_EMAIL”
net-tools
輸入下面的命令可以進(jìn)行安裝工作
sudo apt install net-tools
要確保網(wǎng)絡(luò)環(huán)境在一個(gè)網(wǎng)段,那么就需要設(shè)置網(wǎng)卡為橋接模式。
需要注意的是在選擇網(wǎng)絡(luò)適配器時(shí),選擇自己的網(wǎng)卡。
在Ubuntu上輸入ifconfig,并且在window上輸入ipconfig。只要前面的網(wǎng)段一樣,最后不一樣即可。這樣就可以進(jìn)行下一步的工作了。
tftp
TFTP (Trivial File Transfer Protocol) 是一個(gè)簡(jiǎn)化版的FTP,適合用于簡(jiǎn)潔的場(chǎng)景,比如嵌入式開發(fā)的時(shí)候向下位機(jī)傳輸文件。
安裝tftp的目的是方便開發(fā),在樹莓派上,存儲(chǔ)介質(zhì)是SD卡,如果每次編譯完成后,都需要插拔SD卡,然后將Linux的固件進(jìn)行安裝,這樣非常的麻煩,這里可以采用uboot通過tftp加載Linux的固件的方式進(jìn)行加載。
安裝過程如下:
首先安裝復(fù)位程序
sudo apt install tftpd-hpa sudo apt install tftp-hpa
檢查服務(wù)器的運(yùn)行狀態(tài)
sudo systemctl status tftpd-hpa
打開配置文件
sudo vim /etc/default/tftpd-hpa
編輯的內(nèi)容如下:
TFTP_USERNAME=“tftp” #tftpd程序使用的賬戶 TFTP_DIRECTORY=“/srv/tftp” #目錄 TFTP_ADDRESS=“:69” #端口 TFTP_OPTIONS=“--secure --create” #--secure 不設(shè)置會(huì)有跨目錄的問題 --create是要自己添加的,給客戶端寫入數(shù)據(jù)的權(quán)力
設(shè)置訪問目錄的權(quán)限
sudo chown tftp:tftp /srv/tftp
重啟tftp服務(wù)器
sudo systemctl restart tftpd-hpa
本地測(cè)試tftp服務(wù)器
1.首先在/srv/tftp目錄中新建一個(gè)abc.txt文件。
sudo vim /srv/tftp/abc.txt
2.輸入tftp 127.0.0.1
出現(xiàn)上述的現(xiàn)象,表示測(cè)試成功。
遠(yuǎn)程測(cè)試
需要保證tftp服務(wù)器沒有問題,可以在windows上下載一個(gè)Tftp64的軟件。打開后選擇tftp client選擇傳輸?shù)奈募纯伞?/p>
選擇put按鈕,彈出下面的命令表示成功。如果不成功,需要注意電腦防火墻的設(shè)置問題。
檢查tftp服務(wù)器中的文件,可以正常的見到文件,表示tftp環(huán)境搭建成功。
nfs
安裝nfs目的是一旦開發(fā)Linux上的應(yīng)用程序時(shí),不希望頻繁的傳輸文件,每次在宿主機(jī)上編譯好應(yīng)用程序后,直接拷貝到本地目錄,嵌入式平臺(tái)上的Linux可以通過nfs文件系統(tǒng)訪問到宿主機(jī)上剛編譯好的程序,這樣更加的方便Linux的應(yīng)用程序的開發(fā)工作。
sudo apt install nfs-kernel-server
然后創(chuàng)建一個(gè)nfs的共享目錄,用于存放共享文件。
sudo mkdir /opt/nfs
修改配置文件
sudo vim /etc/exports /opt/nfs 10.1.1.* (rw,async,root_squash)
編輯/etc/exports中的文件如下:
其中10.1.1.*為自己網(wǎng)段的地址信息。
最后重啟nfs即可
sudo systemctl restart nfs-kernel-server
測(cè)試nfs的安裝情況
安裝完成后,可以進(jìn)行nfs客戶端的安裝
sudo apt install nfs-common
然后創(chuàng)建一個(gè)本地的文件夾目錄
sudo mkdir -p /opt/nfs-client
最后掛載即可
sudo mount -t nfs 10.1.1.160:/opt/nfs /opt/nfs-client
當(dāng)在/opt/nfs下創(chuàng)建一個(gè)文件,/opt/nfs-client目錄同樣可以看到,表示成功。
2.2 樹莓派開發(fā)環(huán)境搭建
2.2.1 硬件連接
樹莓派4上的實(shí)際硬件引腳分布如上圖所示,其中需要連接串口RX、TX、GND。
準(zhǔn)備一個(gè)8g以上的SD卡,然后打開Raspberry Pi Imager,選擇樹莓派鏡像燒錄進(jìn)去。
進(jìn)行這一步的目的,是因?yàn)闃漭蓡?dòng)流程需要從SD卡中加載第一階段的啟動(dòng)文件。
默認(rèn)情況下,燒錄的固件,連接上串口后是沒有輸出的,需要自己修改sd卡中的config.txt文件。在末尾加上下面的一句話即可。
enable_uart=1
這樣通過mobaxterm工具打開串口,并且連接上電源后,可以看到如下的輸出
接著輸入用戶名,密碼如下
raspberrypi login:pi Password:raspberry
這樣就可以使用默認(rèn)的樹莓派4串口調(diào)試功能了。
2.2.2 樹莓派4b啟動(dòng)流程分析
簡(jiǎn)述一下樹莓派4b的啟動(dòng)流程是,上電后,樹莓派會(huì)自動(dòng)加載位于SD卡文件中的bootcode.bin文件,該文件是加載到樹莓派的GPU中運(yùn)行,該程序初始化PLL,DDR等,接著讀取SD卡文件中的start4.elf文件去執(zhí)行,該文件執(zhí)行過程中,會(huì)讀取config.txt文件,根據(jù)配置腳本選擇可以執(zhí)行的固件。
往往做嵌入式開發(fā),其底層的啟動(dòng)邏輯是要非常清晰的,這樣才能在任何情況下梳理清楚問題所在,從而確保硬件和軟件層面上的一致性。
上圖基本上展示了一個(gè)通用的嵌入式Linux的啟動(dòng)流程,每一個(gè)階段的特點(diǎn)和功能點(diǎn)都有著很好的描述。
而樹莓派4b上的Broadcom BCM2711的啟動(dòng)遵循以下的流程。
第一階段的bootloader:
第一階段的BootROM一般是固化在芯片的內(nèi)部,在GPU中執(zhí)行,此時(shí)ARM核處于復(fù)位狀態(tài)。
樹莓派4b的BootROM通過EEPROM加載進(jìn)來,4b之前都是SD卡上的bootcode.bin文件。
第二階段的bootloader:
這一階段的boot固件的加載方式都是從SD卡、網(wǎng)絡(luò)、USB等等。
在樹莓派4上,使用的是SD卡中的start.elf二進(jìn)制文件。
start.elf文件去SD的文件系統(tǒng)中找到config.txt文件,然后根據(jù)里面的信息處理boot流程。
這篇文章中,主要修改config.txt配置文件,進(jìn)行uboot的啟動(dòng)流程。
3.交叉編譯工具的安裝與uboot的編譯
3.1 安裝arm 64位交叉編譯環(huán)境
因?yàn)樾枰幾g64位的程序,所以這里需要安裝arm的64位交叉編譯環(huán)境。
https://www.linaro.org/downloads/
從上面的網(wǎng)站中進(jìn)去
建議下載gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz。
下載完成后,放到指定的目錄。
#創(chuàng)建一個(gè)文件夾 sudo mkdir -p /opt/linaro #解壓到指定的文件夾路徑 sudo tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar -C /opt/linaro
更新環(huán)境變量
sudo vim ~/.bashrc
在末尾添加如下的
alias crosscompiler=‘export KERNEL=kernel8;export ARCH=arm64;export CROSS_COMPILE=/opt/linaro/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-’
更新環(huán)境
source ~/.bashrc
3.2 編譯樹莓派上的uboot
首先需要下載代碼
git clone https://github.com/u-boot/u-boot.git
正常的下載完成圖如下:
接著切換分支,然后開始編譯。
cd u-boot git checkout v2020.04-rc3
在編譯之前,首先需要安裝編譯必備的程序
sudo apt install u-boot-tools bison bc make flex libssl-dev ncurses-*
安裝完成后,執(zhí)行
crosscompiler
該命令為環(huán)境變量中定義的命令,可以設(shè)置環(huán)境變量。
make rpi_4_defconfig
直接采用默認(rèn)的配置編譯即可。
make -j $(nproc)
編譯完成后的uboot.bin文件就是可以直接在樹莓派4b上執(zhí)行的程序。
3.3 將u-boot放到樹莓派上運(yùn)行
到這一步就可以將編譯好的u-boot程序放到樹莓派4b上運(yùn)行了。
將樹莓派的SD卡插到電腦上,通過將SD卡中的config.txt重新命令為config.txt.bak。并且新建config.txt。
arm_control=0x200 kernel=u-boot.bin dtoverlay=disable-bt
這三行的意思是
arm_control=0x200 #因?yàn)闃漭?b支持的是64位的架構(gòu),這里用來表示運(yùn)行64位程序
使用uboot
kernel=u-boot.bin # kernel表示運(yùn)行的固件
使能串口
dtoverlay=disable-bt #樹莓派4設(shè)計(jì)的時(shí)候,如果打開了串口調(diào)試,則藍(lán)牙無法使用
將SD卡插入電腦,可以看到uboot正常的啟動(dòng)。
4.樹莓派4b上的Linux編譯和下載
4.1 編譯樹莓派Linux源代碼
目前已經(jīng)完成了樹莓派4b的uboot功能,接下來開始編譯樹莓派的Linux kernel了。
樹莓派單獨(dú)有維護(hù)Linux的代碼分支,可以通過下面的命令進(jìn)行下載。
git clone --branch rpi-5.6.y https://github.com/raspberrypi/linux
進(jìn)入Linux的目錄
創(chuàng)建一個(gè)新的目錄存放編譯好的固件
mkdir rpi_hw
開始編譯
make O=rpi_hw bcm2711_defconfig
去掉MMC/SD/SDIO驅(qū)動(dòng)
make O=rpi_hw menuconfig
進(jìn)入Device Driver選擇去掉MMC/SD/SDIO card support。
保存配置后,就可以編譯了。
make O=rpi_hw -j $(nproc)
為什么要去掉MMC/SD/SDIO驅(qū)動(dòng)?
這是因?yàn)樾枰幾g從網(wǎng)絡(luò)啟動(dòng)的驅(qū)動(dòng),所以不需要在樹莓派的SD卡里面進(jìn)行操作。
編譯完成后,可以在rpi_hw/arch/arm64/boot中找到編譯好的文件。
將編譯完成的Linux內(nèi)核文件放到
sudo cp rpi_hw/arch/arm64/boot/Image /srv/tftp/
4.2 將編譯好的Linux固件運(yùn)行
在將編譯好的固件通過uboot加載到RAM中運(yùn)行的期間,首先需要明白樹莓派4b內(nèi)存的分布情況。
通過uboot中的bdinfo命令,可以看到樹莓派4b上有兩塊bank,第一塊bank在0x00000000,第二塊在0x40000000。
而樹莓派4b,當(dāng)從SD卡中加載Image文件時(shí),加載到DRAM的0x8000的地址處開始運(yùn)行。
當(dāng)然,地址也可以在uboot中設(shè)置,Linux會(huì)重新將代碼重定位。
此時(shí),需要在uboot中設(shè)置啟動(dòng)信息了。
首先設(shè)置uboot的靜態(tài)ip地址
setenv ipaddr 10.1.1.100 #設(shè)置開發(fā)板的靜態(tài)地址(自定義) setenv serverip 10.1.1.160 #設(shè)置服務(wù)器的地址 setenv netmask 255.255.255.0 saveenv reset
上述操作設(shè)置了ip地址接下來設(shè)置啟動(dòng)
setenv kernel_addr_r 0x8000 setenv kernel Image setenv netboot ‘tftp ${kernel_addr_r} ${kernel} && booti ${kernel_addr_r} - ${fdtcontroladdr}’ setenv bootcmd ‘run netboot’ setenv bootargs ‘console=ttyAMA0’ saveenv reset
可以顯示如下:
最后啟動(dòng)后報(bào)錯(cuò)
這個(gè)很正常,目前沒有rootfs。但是現(xiàn)在Linux的內(nèi)核可以正常的加載和調(diào)試了。
下面來掛在rootfs。
5.根文件使用
關(guān)于通用根文件系統(tǒng)的制作過程,這篇文章就不提了,現(xiàn)在主要描述如何使用。
5.1 uboot中設(shè)置啟動(dòng)項(xiàng)
首先在uboot中設(shè)置路徑。
setenv nfsroot /opt/nfs/
設(shè)置啟動(dòng)參數(shù)
setenv bootargs “console=ttyAMA0,115200 root=/dev/nfs rw nfsroot=${serverip}:${nfsroot},v3,tcp ip=$ipaddr:$serverip::$netmask:off”
保存配置
saveenv
5.2 插入SD卡掛在到虛擬機(jī)上
首先將U盤掛載到虛擬機(jī)上
可以看到出現(xiàn)兩個(gè)磁盤
其中:
rootfs為L(zhǎng)inux根文件系統(tǒng)
boot為可以在windows上訪問的ext32文件
可以將rootfs里的文件全部拷貝到/opt/nfs/
sudo cp * /opt/nfs/ -R
在/opt/nfs目錄下,新建一個(gè)file的文件夾,把boot里面的文件全部拷貝進(jìn)去即可
sudo mkdir -p /opt/nfs/file sudo cp * /opt/nfs/file/
5.3 修改文件腳本
需要修改
sudo vim etc/fstab
新增如下文件
10.1.1.160:/opt/nfs/file /boot nfs defaults,vers=4.1,proto=tcp 0 0
其目的是將默認(rèn)的兩個(gè)項(xiàng)列表屏蔽掉,只需要掛載nfs里面的文件系統(tǒng)即可。
改完后,插上SD卡,就可以正常從tftp中獲取Linux的內(nèi)核固件,并且能夠從nfs文件系統(tǒng)中掛載根文件系統(tǒng)了。
如果發(fā)現(xiàn)需要密碼,或者密碼忘記了,可以進(jìn)入
cd /opt/nfs/ sudo vim /etc/passwd
將中間的x刪掉。
在Linux中,默認(rèn)x表示需要密碼進(jìn)入。
6.小結(jié)
本文從樹莓派整個(gè)Linux系統(tǒng)的環(huán)境搭建和樹莓派的啟動(dòng)進(jìn)行一定的分析。對(duì)樹莓派的boot、u-boot加載Linux的kernel,以及掛載nfs文件系統(tǒng)做了一些實(shí)驗(yàn)。
最后的自己制作根文件系統(tǒng)的部分,采用了樹莓派默認(rèn)的根文件系統(tǒng),如果需要自己裁剪制作,可以進(jìn)行定制操作。
整個(gè)嵌入式Linux開發(fā)和環(huán)境搭建過程都可以在樹莓派4b上很好的進(jìn)行測(cè)試,萬變不離其宗,掌握了嵌入式開發(fā)的流程和工具,做應(yīng)用和做驅(qū)動(dòng)開發(fā)都十分的方便和高效。
由于時(shí)間關(guān)系,當(dāng)前還有一些實(shí)驗(yàn)沒有完成,比如Linux上的應(yīng)用開發(fā),還有驅(qū)動(dòng)開發(fā)等等,還有jlink調(diào)試等等。
樹莓派4b上學(xué)習(xí)Linux的使用和啟動(dòng)非常的方便,價(jià)格也非常的合理,是一塊不錯(cuò)的開發(fā)平臺(tái)。
原文標(biāo)題:樹莓派4 嵌入式Linux開發(fā)過程詳解
文章出處:【微信公眾號(hào):嵌入式IoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
責(zé)任編輯:haq
-
Linux
+關(guān)注
關(guān)注
87文章
11183瀏覽量
208565 -
樹莓派
+關(guān)注
關(guān)注
116文章
1684瀏覽量
105421
原文標(biāo)題:樹莓派4 嵌入式Linux開發(fā)過程詳解
文章出處:【微信號(hào):Embeded_IoT,微信公眾號(hào):嵌入式IoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論