開發與維運

為你的硬件自動化統一構建root和firmware

本文關鍵字:Buildroot,coreboot as Buildrom

前面《基於虛擬機的devops套件及把dbcolinux導出為虛擬機和docker格式》系列文章中,參照LFS,我們曾手動自建過交叉編譯環境和linux,完成了包括gcc as 開源toolchain,linux as os kernel,busybox as開源os rootfs,各種libs的所有手工化構建步驟,不過僅限於在PC上,和x86之間進行,都沒有考慮進我們現在除PC外的其它使用linux的硬件,—— 這就是嵌入式平臺及特化PC,它們甚至是我們目前硬件平臺中的絕大部分,如路由器和手機(nas,laptop也算),—— 雖然說linux對嵌入式都有支持,構建的流程大同小異。它們跟PC平臺相比,對構建的需求還是有點不太一樣:

首先,但嵌入式硬件多樣,有著各種各樣的非x86 CPU和cross compile需求,採用的一些版本也是PC上的特化版本,如libc。libc是程序與內核交流的媒介與用戶編程接口,,嵌入式上往往使用ulibc.

而且,嵌入式中,firmware跟os,甚至app的界限非常不明顯,往往高度耦合,前面我們在《Boot界的”開源os“ : coreboot,及再談雲OS和本地OS統一裝機的融合》中說到,firmware編程是OS前面的那塊軟件編程,嵌入式平臺的firmware與os往往高度偶合,往往firmware直接就是boot loader,使用uboot這種方案。程序要求也不一樣,嵌入式往往就一到幾個守護程序持續運行,簡單的自啟腳本即可,除了像帶需要帶安裝APP支持的智能路由器需要像openwrt這種擁有類PC包管理的之外。

而且他們使用構建結果,安裝系統的方式,PC跟嵌入式也不一樣,它們需要rootfs尺寸要裁剪非常小,它往往是一個靜態的firmware或rootfs鏡像,直接刷到嵌入式硬件上的一塊靜態的固定存儲量的ROM上用於承載OS。

因此針對嵌入式的構建,這些支持往往分別分散在各個廠商的手中。

—— 所以,如果有各種嵌入平臺,還要考慮進coreboot as 開源firmware,,為什麼不把for pc,for embededs,for rootfs,for firmware編譯和安裝統一考慮進這個綜合構建呢?

—— 只是,因為這裡面的要處理的工作和複雜度實在太高太大量(這已經是製作一個linux發行版,甚至硬件的工程量了),難於用一個框架來述說。你看LFS就需要一本書。這套構建工作最好是自動化的。要用一套腳本來處理的話就最好了。

—— 幸好,build firmware和build root其實是一個很相近的過程,都是從交叉編譯工具的構建和驅動開始, (其實,區分這二者也很簡單。一個是硬盤上的OS,一個是沒進入OS之前的那個硬件初始化(firmware)中的OS)。這二者統一,自然而然。

市面上終於也出現有這類工具,Cross-ng和Build root,OpenEmbedded,openwrt,就是這樣的工具/環鏡。如cross-ng只處理交叉構建,buildroot就是整合toolchain(它也可以使用external toolchain built from cross-ng),kernel,bb,rootfs,libs的工具,只限於直到生成打包的文件系統。不往發行版本一步,coreboot,firmware的OS,buildroot有點像coreboot as buildrom,。openembeded可以直接用來構建發行版。openwrt也跟openembeded一樣生成發行版不過它大都針對路由器。

這裡面最大的好處是,1,當這類工具統一在同一套腳本上,它可以實現all in one,self contained,所有的部件保持同一風味,比如linuxkernel,bb是同flavor的,它們使用kconfig,且將編譯過程中所有涉及到的大件都menuconfig化,如果libc也可以,coreboot也可以,不是更好麼。在build root內部就是這樣做的,它增加了glibc-menuconfig,linux-menuconfig這樣的東西。使得腳本更統一,更in flavor。2,both for embed and pc,buildroot本來就是for嵌入式的,像build root同時支持了ublic和glibc庫和各種mainboards,cpu。這樣就給了我們融合多套硬件製作同一套軟件鏡像上的統一構建用的codebase,,而coreboot也是for 嵌入式的,我們看到其soc下有很多欠入式,廣大嵌入式的構建工作更應應用coreboot的統一設計而不是分散廠商的。— 這些可以用同一套codebase生成融合硬件使用的鏡像不好麼?。3,可以統一使用,其寫好的firmware可以在虛擬機中,如qemu中測試(qemu因此也是firmware和build root眼中的一種抽象主板)。Qemu可以單獨餵給一個firmware,也可以同時結合餵給一個firmware+OS的組合。4,可以統一讓融合硬件使用同一個codebase,談到硬件融合,我們前面有很多例子,虛擬appliance+一個有融合作用的HOST as shell也可以解決硬件融合的很多事情,比如PD的融合模式,而現在,像一些激進的硬進如purism,librem(一個可以發展裝有linux的手機。類ubuntu touch一體手機電腦融合OS的硬件產品)都ship了Coreboot

帶著這些觀點,我們來研究build root和coreboot的腳本

其中的所有原理,都是我們在《基於虛擬機的devops套件及把dbcolinux導出為虛擬機和docker格式》曾手動自建交叉環境和編譯之後kernel,bb,libs,所涉及到的那些,Coreboot和Buildroot的編譯都能在一臺unix派生系的host上完成,要求host上一個toolchain加少量必要的庫就差不多了。因為它們都面向構建基礎套件。

Build root

Buildroot可以在本機上直接構建,官網提到GCC要4.4以上,HOST要用常見unix派生系os。。當然最新發布的buildroot已經用上了vagrant虛擬機,這樣就省了好多工作(如果要在host手動安裝編譯需要的東西,參見那個vagrantfile中要安裝的包即可,)。

我們僅講解自動的。在vagrant中,我們發現最新的buildroot都使用到gcc7來編譯了。buildroot(2019.8)大約有10000多個package(實現一個發行版直接可以拿來作為倉庫),每個package下面都有.mk和.config.in,package源碼都是一次編譯即時下載到src/dl的。你也可以make source把它引用的packages源碼下好,裡面有board/qumu,生成的output中,output/中良好排序著交叉三元組:build, target, host中的臨時文件,還有我們要得到的最終的東西,images,可以對比《基於虛擬機的devops套件及把dbcolinux導出為虛擬機和docker格式》來理解和使用。

這裡需要搞清build root涉及到的devops工具的關係和區別:

vagrant和packer都是hashicorp的Devops七件套之一。packer是提供一個初始鏡像,控制虛擬機如VB,PD(我們講過PD和VMWARE方面的例子),自動化輸入。inplace生成新鏡像。vagrant是命令行版本的虛擬機管理器。它可以管理VB,PD等(provoders),如果有可用鏡像box,可在vagrant配置文件中寫明,然後用vagrant up起來給任何一個provider使用,up後可在虛擬機內幹任何事情,關機後不導出鏡像

它們的關係才是它們的重點,1,用packer也可以製作vagrant使用的鏡像。2,Vagrant技術原理它跟packer差不多,裡面也有provisioner等等。也是控制虛擬機,也有自動輸入和配置文件,只是表現形式產出結果不一樣。3,它們共享很多其它機制,如都可以在host/guest間用nat,Nat方式也可以在本地搭建一個也有http sharing。只是配置文件內的寫法大同小異。
下面來談在vagrant guest os中使用host的VPN。比如我的VPN在HOST的127.0.0.1:1087端口,虛擬機裡面的是不可能獲得本地vpn的,所以我們需要在vagrant files中。加一句。export http_proxy=http://10.0.2.2:1087;export https_proxy=http://10.0.2.2:1087;因為用的是nat 網絡。

加在這個位置:
config.vm.provision 'shell', privileged: true, inline:"
export http_proxy=http://10.0.2.2:1087;export https_proxy=http://10.0.2.2:1087
sed -i 's|deb http://us.archive.ubuntu.com/ubuntu/|deb mirror://mirrors.ubuntu.com/mirrors.txt|g' >>/etc/apt/sources.list
...
config.vm.provision 'shell', privileged: false

如果不在vagrant虛擬機中開啟VPN支持。可能會卡在Downloading and extracting buildroot 2019.08不動。這其實也是從前文《packer中學到的》,,可在打開的虛擬機窗口中測試box os用戶名密碼都是vagrant,ifconfig看到,在本機是訪問不到nat內部的不能ssh [email protected]

Build Coreboot

Coreboot最新版是coreboot-4.10,使用linux kernel式的kconfig,和bb式的可視裁剪配置。所以它跟build root是flavor的,也對qemu有board支持。。跟buildroot的職責一樣,完全對引導期,進入OS前的firmware OS的構建。

Coreboot並沒有使用vagrant,你得在一臺HOST上配置再編譯。也是配置toolchain(因為稍後Qemu x86,所以用any toolchain),mainboard那些,不同的有payload,對於mainboard,如果是測試,可以完全選擇使用Qemu 模擬x86.

之後make一路通過。

我們的改變

如何集成到我們的cohdevbox srctree中。及你們的工程中。

上面提到vagrant和packer同基礎,工作方式和配置都大同小異,在我們現在的實踐文章中,都是用的packer,那麼為什麼不能把vagrant當packer用呢。Vagrant還可以避免出現packer那種一旦失敗,全部從0重來的尷尬。即,在Vagrant退出按ctrlc,再重新執行up,它會重用上次grant provision的結果(因為它是虛擬機嘛)。這跟packer不一樣,packer的構建不會重用上次provision的結果,會重新構建。雖然它不產生鏡像(實際上那個鏡像就是你的provider在你硬盤上的鏡像,關機複製得到和packer一樣的結果)。

我們會在srctree中提供一份編好的tinycorelinux硬盤鏡像作為vagrant用的box。然後整個源碼會deprecated packer。只用vagrant.然後在其中通過配置文件手動編譯avatt,結合修改,代替現在的cohdevbox srctree。

最後,我們可能全程用qemu作虛擬機,因為qemu支持命令行提供firmware,它可以統一測試firmware和rootfs,完全可以用qemu來替換VirtualBox,qemu是命令行虛擬機工具。與其他的虛擬化程序如 VirtualBox 和 VMware 不同, qemu可以模擬CPU(全虛擬),甚至餵給firmware。但vb,pd都不可以。還有一點,QEMU不提供管理虛擬機的GUI(運行虛擬機時出現的窗口除外),也不提供創建具有已保存設置的持久虛擬機的方法。除非您已創建自定義腳本以啟動虛擬機,否則必須在每次啟動時在命令行上指定運行虛擬機的所有參數。

我們選用的host平臺是osx,不能用到kvm/qemu,因為kvm是linux的。在osx上我們不打算用到任何加速方案(半虛擬)。因為是測試。直接使用qemu默認的console窗口而不使用任何GUI管理器,vagrant可以通過libvirt用上qemu。

注意到coreboot編譯GCC toolchain等輸出信息很精簡。而我們在《packer》文中不能控制選擇過程warning等信息。所以決定研究後採用。


(此處不設回覆,掃碼到微信參與留言,或直接點擊到原文)

qrcode.png

Leave a Reply

Your email address will not be published. Required fields are marked *