來源:公眾號【魚鷹談單片機】,ID ??:emOsprey
Yocto 是什么?很多道友第一次聽到時估計都是一臉懵逼。當初魚鷹從領導處了解這個技術時,完全不知道是什么,只能摸著石頭過河。
?buildroot辛酸史
在此之前,領導剛剛讓魚鷹學習了 buildroot 編譯內核鏡像,因為我們有個老項目的鏡像就是用它編譯的。
以前這些鏡像都是老外維護(魚鷹目前在世界500強外企,有時間聊聊在外企這些年學到了啥,歡迎關注魚鷹談單片機),我們只要從指定地址獲取鏡像,用工具燒錄SD卡鏡像就行。
后面領導想國內也能維護鏡像,能自己編譯鏡像,于是讓魚鷹學習鏡像編譯(以前和領導聊過發(fā)展方向,知道魚鷹想往 Linux 方向發(fā)展,因此給了機會)。
Buildroot 很多年前魚鷹也了解過,也編譯過,感覺不是特別難,覺得任務應該很快能完成。
但沒想到,搞了半個多月才搞定,印象最深刻的就是 2.5 G左右的開源資源下載。以前編譯鏡像時,從來沒遇到這些問題,都是半天到一天左右就搞定了。
現(xiàn)在想想,有這兩點原因:
1、那些年,github 可以正常上網,很多國外資源都能輕松下載。
2、目前的鏡像依賴的開源庫太多,也太老了,以前只是為了學習Linux內核,只要基礎的組件就行。
因此很順利編譯 uboot、內核、文件系統(tǒng)(鏡像三大件)。
現(xiàn)在有些資源下載實在太慢,只能各種找資源,另外從 gitee 中轉,總算是下載完成了(還好支持離線下載安裝方式)。
但是 qt 這個功能最終還是沒裝上,不知道啥原因,因為不重要,就沒管了。
另外很多資源有指定的 hash 值,你只能下載相同 hash 值的資源,否則即使你修改了 hash 值適配新資源,最終可能導致系統(tǒng)不兼容。
還有 buildroot 環(huán)境本身的安裝也有點麻煩,也需要時間熟悉。
?Yocto苦難史
后來轉 Yocto 開發(fā)后,發(fā)現(xiàn)學習難度比 buildroot 上升了十倍,資源(硬盤空間)消耗差不多也是十倍,但是熟悉后,簡直 TMD 就是為嵌入式而生。
當時自己的 Ubuntu 是 18.04,因為有個老項目的編譯需要這個版本才能正常編譯。
而 Yocto 的推薦系統(tǒng)應該是 20.04 以上,最少剩 120 G硬盤空間:
IMX_YOCTO_PROJECT_USERS_GUIDE.pdf
魚鷹不想重裝Ubuntu系統(tǒng)(那個時候還不知道用 docker),于是走了一個岔路,遇到各種軟件不兼容問題,比如 gcc (只能下載源碼重新安裝)、python,有些推薦安裝的軟件版本無法順利安裝。repo 工具本身由于國內網絡環(huán)境原因,也得使用國內鏡像才順利。
最后生成 SDK 時,又卡在最后一步,沒找到 dnf 這個python工具,還好通過別的命令生成了工具鏈,否則如果卡在編譯鏡像的最后一步,就麻煩大了(后面 docker 解決以上痛點)。
bitbake meta-toolchain
總之,問題很多。幾天時間,雖然開發(fā)環(huán)境問題解決了(有了docker,半天不用就能搞定),但是和 buildroot 一樣,下載問題又遇到了,這次更狠,直接 30 G 資源下載(因為國內基本不使用 Yocto,即使用,imx6ull 居多,所以很難找到合適的)。
搞得魚鷹一點脾氣也沒有,只能向供應商求助,拿到了他手里提前下載好的資源。
這樣資源齊全了,終于可以開始編譯了。
編譯過程還算正常,只是相比 buildroot,編譯賊慢,資源消耗極大(非常簡單的一個進程,可能需要幾百 M 資源,這也能看出為啥整個鏡像需要100多G空間了)。
這里有個賊好用的命令,可以在出現(xiàn)錯誤時,不會立即打斷,繼續(xù)運行其它任務。
bitbake?xxx?-k
另外推薦一個Yocto入門視頻:B站:iMX6ULL采用Yocto構建嵌入式Linux系統(tǒng)
總之開發(fā)環(huán)境搭建、資源提前下載好后,編譯也算相當順利了。
三大件一個不缺,同時還能生成 SD 卡鏡像。
為什么 Yocto 這么難學,資源消耗這么大,還是這么多大廠都在用?
比如 NXP、BMW、Amazon 、Facebook (Meta)、 General Electric 等。
對于現(xiàn)代計算機而言,資源消耗已經不是大問題,可維護性、靈活性、定制性、兼容性、生態(tài)才是首先要考慮的問題。而這些 Yocto 都具備了。
靈活性和定制性:Yocto項目提供了靈活的工具集和開發(fā)環(huán)境,允許開發(fā)者自由選擇資源的使用,或者完善特定的組件(包括這些組件的特定版本)。這種靈活性使得開發(fā)者可以根據自己的需求定制Linux發(fā)行版,從而滿足特定硬件平臺的需求。
避免重復工作:Yocto項目鼓勵跨各種應用程序和設備類型的創(chuàng)新,支持多種硬件架構,如x86、ARM、RISC-V、PPC和MIPS等。通過共享技術、軟件堆棧、配置和最佳實踐,Yocto項目幫助開發(fā)者避免從零開始,減少重復工作和不必要的維護。
強大的構建系統(tǒng):Yocto項目的核心是BitBake,這是一個高效的任務調度器和執(zhí)行系統(tǒng),能夠處理復雜的依賴關系,并優(yōu)化構建過程。BitBake能夠確保構建任務按正確的順序執(zhí)行,從而提高構建效率和可預測性。
豐富的生態(tài)系統(tǒng):Yocto項目擁有一個活躍的社區(qū)和豐富的文檔資源,這為開發(fā)者提供了強大的支持。社區(qū)成員包括硬件制造商、操作系統(tǒng)供應商和獨立顧問,他們共同為項目貢獻資源和信息,形成了一個強大的生態(tài)系統(tǒng)。
標準化和兼容性:Yocto項目提供了標準化的構建流程和工具,這有助于不同開發(fā)者和團隊之間的協(xié)作。通過使用Yocto項目,開發(fā)者可以確保他們的定制Linux系統(tǒng)在不同硬件平臺上具有高度的兼容性和可移植性。
優(yōu)化的資源利用:Yocto項目允許開發(fā)者精確地創(chuàng)建嵌入式設備所需的內容,只需添加設備絕對需要的功能支持或包。這有助于優(yōu)化系統(tǒng)性能,減少不必要的資源占用,從而為嵌入式和物聯(lián)網設備提供更高效的解決方案。
可維護性和可擴展性:Yocto項目的設計允許用戶使用自主開發(fā)的操作系統(tǒng)或商業(yè)操作系統(tǒng),在遷移時不會丟失優(yōu)化或功能。此外,商業(yè)操作系統(tǒng)也可以使用Yocto項目作為上游資源,從而確保最大化代碼重用。
支持多種構建目標:Yocto項目不僅可以用于創(chuàng)建Linux發(fā)行版,還可以為裸機開發(fā)生成實時操作系統(tǒng)(RTOS)工具鏈,如Zephyr項目所做的那樣。
以上是 AI 給出的答案。
下面再結合魚鷹實際開發(fā)經驗談談為啥 Yocto 大法好。
1、開發(fā)環(huán)境
docker 技術解決了環(huán)境搭建問題,因此環(huán)境搭建不再是問題。
年少不知docker好
2、可以編譯各種代碼
我們知道,一個項目,涉及到各種編程語言,比如 C/C++、Python、Java 等,涉及各種平臺,比如 u-boot、Linux、MCU、qt,各種架構?,arm、risc-v,x86 等,而 Yocto 可以把這些代碼都編譯好,放在一個壓縮包里面,直接拿就行了。
而且同一套 meta,可以輕松編譯?x86 和 arm,這樣在沒有arm板的情況下也能進行一些開發(fā)調試工作,自動化測試也更容易。
3、支持 qemu 調試
原生支持 qemu 調試,不過這一塊魚鷹沒搞太懂,搞懂了,對開發(fā)效率又是一大提高了。
4、定制化
重點來了,估計這個才是各個大廠喜歡 Yocto 的原因。
很多時候,我們的工作是建立在別人的基礎上,比如我想在 ubuntu 里面加一個 qt 界面。
這個時候,如果已經有現(xiàn)成的 Ubuntu,那搞個 qt 就簡單許多了。
同理類似,Yocto 項目里面有很多Linux發(fā)行版,包含各種組件(可能有幾百上千個),完全可以自主添加或刪除某些組件,并且這些組件版本也有社區(qū)負責維護更新。
比如某個工具 vim 的某個版本,需要 Linux 內核某個版本以上才行,這些常用工具的兼容性,都會被處理好,你只要下載一個poky(Yocto的參考實現(xiàn))發(fā)行版,指定某個版本,就能編譯出整個鏡像(就是下載的時候,可能又要花一些時間了,因為可能依賴的組件版本不同,需要重新下載)。芯片廠家也會在這些基礎上,添加自己的特殊化定制。
另外除了整個鏡像的特殊化定制,單個組件,單條代碼都能修改。
最常用的,比如修改設備樹、內核代碼、驅動,這些都會以補丁的形式添加到基礎 Linux 代碼中(不會修改源碼)。
而如果要升級 Linux 內核到最新版本,也非常容易,一般 poky 會同步最新內核,同時會把依賴的組件一并升級,這樣在你的項目修改可能就只是一個 Poky 的一個commit 修改而已(如果修改了內核代碼,可能需要同步修改一下),但是那些組件,比如 vim、nano、ssh 等工具會同步升級,不需要你關心。
Yocto生成的鏡像也有多種選擇,比如
core-image-minimal:這是一個非常基礎的鏡像,包含必要的系統(tǒng)工具和Linux內核,適合作為定制更復雜系統(tǒng)的基礎
core-image-sato:這是一個為桌面環(huán)境優(yōu)化的標準鏡像,包含了更多的軟件包和工具,適合用于桌面或展示設備
core-image-full-cmdline:這個鏡像包含了完整的命令行工具集,但不包含圖形界面,適合需要完整命令行環(huán)境的嵌入式設備
core-image-multimedia:這個鏡像包含了多媒體相關的軟件包,適合需要音頻和視頻處理能力的設備
你可以選擇在這些鏡像基礎上添加自定義的功能。
并且如果有些組件代碼,你不喜歡,也可以隨時修改,這種修改不會修改源碼,而是以補丁的形式修改到另一個編譯環(huán)境中,這樣可以保證源碼的純粹。
5、項目實用性
你有一塊 Linux 板子V1,根據當前硬件適配了代碼,發(fā)現(xiàn)有些問題,需要改硬件,變成 V2,另外可能還有其它 MCU 的代碼也需要同步修改,而老版本板子也有在用。
如何處理這些依賴問題。
古老的方法是,人工維護兩個環(huán)境依賴差異,高級一點通過腳本或者 repo 工具維護。
而 yocto 借助 kas 工具,可以完美處理這種情況,meta 倉庫里面同一個分支可以同時擁有兩款板子的信息,只要在編譯前,setup 自己需要的機器類型就可以把對應的依賴處理好,再也不會出現(xiàn)Linux 和 mcu 不兼容情況了。
而且使用 kas 可以在 V1 的基礎上進行 V2 的差異修改,只要把差異加上就行,避免重復造輪子,或拷貝或切分支。
6、SDK
可以輕松生成各種SDK,安裝后適用于上層應用開發(fā),而不需要占用太多空間,這樣不會因為一個小小的功能而安裝整個 Yocto 開發(fā)環(huán)境了。
標準SDK(Standard SDK):這種SDK包含了用于應用程序開發(fā)的工件,無論是引導加載程序、Linux內核開發(fā),還是其他用戶空間軟件。它提供了一個交叉開發(fā)工具鏈和庫,這些工具和庫是針對特定圖像優(yōu)化的。你可以使用標準SDK獨立開發(fā)和測試代碼,這些代碼旨在運行在某個目標機器上。
可擴展SDK(Extensible SDK):除了包含標準SDK的所有功能外,可擴展SDK還提供了工具,允許你輕松地向圖像中添加新的應用程序和庫,修改現(xiàn)有組件的源代碼,在目標硬件上測試更改,并輕松地將應用程序集成到OpenEmbedded構建系統(tǒng)中??蓴U展SDK安裝在任何機器上,并且可以用來開發(fā)應用程序、圖像和內核。
本地SDK(Native SDK):這種SDK的目標是在目標設備上運行,適用于那些功能足夠強大的嵌入式設備,可以作為開發(fā)環(huán)境使用的情況。本地SDK包括頭文件、庫和工具鏈,允許在目標設備上直接進行應用程序的開發(fā)和測試。
交叉開發(fā)SDK(Cross-development SDK):這種SDK用于在開發(fā)主機中生成目標機器的二進制文件。它包含了交叉編譯工具鏈、庫、頭文件和二進制文件,以及可能的其他實用程序和應用程序。
這才是真正的大雜燴,包含了嵌入式軟件所需的資源,開發(fā)、編譯、調試,全給你考慮好了,你值得擁有。
7、生態(tài)
有很多meta開源,拿來就能用,很多芯片廠商也有適配 Yocto 環(huán)境,擁有眾多開發(fā)者維護 Yocto,生態(tài)好。
最后在聊聊缺點
1、資源消耗大(每個任務都有單獨的編譯環(huán)境)。
2、開始編譯時速度非常慢,因為它需要在主機上編譯各種工具。
3、入門困難,學習曲線陡峭,但適合復雜項目的維護工作。
4、資源嵌套深,不容易找,也不容易理解編譯過程。