在MacOS上利用docker構建buildroot
之前有聽說過docker,但是一直沒有使用過。最近終於下定決定使用了一下docker,感覺docker用於跨作業系統的軟體工具使用還是比較友好的。
適用人群
本文忽略的部分Linux軟體包安裝的過程,需要讀者有一定Linux操作基礎,具有軟體包查詢與安裝能力。
Docker的基本用法
在使用docker時,首先需要安裝docker。安裝完成後,通過從dockerhub上下載不同系統環境的image,然後執行相應的image,完成docker的執行操作。
在docker的執行的過程,是通過docker命令呼叫image進行的執行,image執行的實體叫做container。image和container的關係比較像網咖系統的關係,網咖系統開機會載入作業系統,並且使用者可以在作業系統中進行操作和修改;當系統關機重啟後,再次開機的系統不會保留使用者的更改,會還原成原本最初的系統狀態。docker的過程與之相同,在docker使用image啟動的container中,使用者在container所做的操作並不會儲存下來,而是會在使用者退出的時候清除。
如果使用者希望儲存下container中的修改,則需要將container儲存成一個新的image,實現對修改的儲存;或者使用共享磁碟的形式,將外部系統的目錄共享到container內部,共享磁碟上的修改會被保留。
從Docker Hub上下載image
docker官方提供了image的下載渠道dockerhub,地址為:https://hub.docker.com。
以Ubuntu為例,在dockerhub上,可以找到Ubuntu的image下載頁面【https://hub.docker.com/_/ubuntu】,在該頁面中可以看到很多不同的Ubuntu的版本資訊,通過
docker pull ubuntu
可以完成對Ubuntu最新image的下載,也可以通過tag頁面中根據tag尋找到所需的image,對指定的image進行下載。例如下載Ubuntu 1804的image,命令如下:
docker pull ubuntu:18.04
下載完成後,本地通過docker images命令可以看到所下載的映象了。
REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 18.04 7698f282e524 4 weeks ago 69.9MB
由於這個映象只是一個最小的系統環境,包含了軟體包安裝命令apt,所以這個映象很小。如果後續需要裝更多的軟體包,並且建立新的image,新的image的尺寸會變大。
執行image
使用docker執行image的命令如下:
docker run ubuntu:18.04 bash
上面的命令是通過docker呼叫了ubuntu:18.04image中的bash。但是該命令一閃而過,沒有留下任何痕跡。這並不是執行錯誤,而是因為bash執行完成之後退出了。如果不希望執行後退出,而是留在終端裡,可以通過下述命令來進行執行:
docker run -it ubuntu:18.04
上述命令執行完成後,可以停留在shell中,該shell是docker所執行的Ubuntu image的container的shell,可以看到命令提示如下:
root@7ab5341e698c:/#
進入container後,使用者為root,容器編號為7ab5341e698c,停留的目錄為“/”。接下來,就可以在容器內進行各種操作了,可以通過apt命令去安裝自己所需的軟體。
!!注意!!
退出容器時,如果直接使用exit命令會導致容器退出,所有容器內部的更改將會丟失。如果只是想離開視窗而不退出容器,需要使用“ctrl + p,ctrl + q”這組命令來離開容器,容器將會在後臺保持執行。容器在後臺執行的狀態可以通過“docker ps”進行檢視,例如:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7ab5341e698c ubuntu:18.04 "/bin/bash" About an hour ago Up About an hour vigilant_kapitsa
通過上述命令可以看到,容器在後臺執行,命令的ID為“7ab5341e698c”。如果希望再次進入到容器中,則可以通過attach命令再次進入到容器中。例如:
docker attach 7ab5341e698c
再次返回容器中,會繼續看到容器內部shell的執行狀態。如果返回容器中時,容器內部的shell正在執行命令,則會在shell處卡住。在shell處卡住時,通過“ctrl + c”命令能夠結束當前命令的執行,也可以通過“ctrl + z”命令將執行的程式掛起,需要時通過“fg”恢復掛起程式的執行。
需要注意的是,在容器執行時,多個視窗通過attach命令連線容器,會進入到同一個shell中,導致shell的搶佔,所以要儘量使用多個attach操作連線同一個container。
儲存container
在docker執行過程中,安裝好所需的軟體工具後,可以通過“docker diff containner”命令看到有哪些修改,例如:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7ab5341e698c ubuntu:18.04 "/bin/bash" About an hour ago Up About an hour vigilant_kapitsa $ docker diff 7ab5341e698c C /root C /root/.viminfo A /root/.vimrc
通過上述命令,可以看出在容器中,新增了viminfo和vimrc檔案。為了儲存這些修改,可以通過commit命令將container儲存成一個新的image。命令如下:
docker commit -m "Add vimrc and viminfo" 7ab5341e698c myubuntu_1804:v0.1
通過上述命令,實現通過container 7ab5341e698c建立了一個名字為myubuntu_1804,tag為v0.1的image。下次執行docker的時候,可以直接執行該image。執行命令如下:
docker run -it myubuntu_1804:v0.1
通過該image執行的container中,包含了之前對viminfo和vimrc的更改,實現了對原容器的儲存。
MacOS
在MacOS上,預設使用的檔案系統是不區分大小寫的,這對於Linux編譯來說會出現問題,所以需要建立一個區分大小寫的擴充套件磁碟來儲存buildroot專案檔案。
在MacOS上,通過磁碟管理工具,可以在原有磁碟上新增一個新增到原磁碟上的卷宗。該卷宗可以與原磁碟共享儲存空間,同時具有獨立的磁碟格式。
新增卷宗時,將磁碟格式設定為“APFS區分大小寫”,即可創建出一個新的區分大小寫的卷宗。至此,MacOS上的磁碟準備工作就緒。
編譯Buildroot
Buildroot是一個Linux平臺上快速構建嵌入式Linux系統的框架,它可以使用menuconfig進行配置,實現快速構建Linux工具鏈、rootfs等環境的工具。
從Buildroot的官方網站上可以下載到Buildroot的原始碼包,網址在:https://buildroot.org/download.html。下載完成後進行解壓縮,即可得到Buildroot的工作目錄。
在該目錄中,存在configs目錄,其中包含了預設的config資訊,可以通過預設配置快速實現構建。
下文中,將使用”qemu_mips64el_malta_defconfig”作為預設配置,來說明Buildroot的基本使用方法。
Docker共享磁碟
為了能夠在docker內部使用Buildroot,可以通過使用共享磁碟的形式將Buildroot掛載到docker內部,而不用將Buildroot放在容器的檔案系統內部。這樣能夠很方便的保留Buildroot的編譯結果,而不用通過儲存container的形式去儲存變更。
由於使用了共享磁碟作為Buildroot的儲存環境,所以需要注意的是:
該磁碟必須是區分大小寫的,!!否則部分軟體包編譯會報錯!!
該磁碟必須是區分大小寫的,!!否則部分軟體包編譯會報錯!!
該磁碟必須是區分大小寫的,!!否則部分軟體包編譯會報錯!!
可以通過以下命令將共享目錄掛載到container內部:
docker run -it -v ${PWD}:/dockershare myubuntu_1804:v0.1
上述命令中,${PWD}指的是當前目錄(全路徑),”/dockershare”指的是container內部可以看到的共享目錄路徑(全路徑)。上述命令執行完成後,即可將當前目錄掛載到docker container內部,也可以通過將${PWD}替換成其他全路徑,實現指定路徑的掛載。
需要注意的是,外部路徑一定是儲存了Buildroot的路徑,並且該路徑中可以存放區分大小寫的檔案。
配置
通過載入共享磁碟的方式進入容器後,可以進入”/dockershare/buildroot-2019.05”路徑(本文下載的是2019.05版本的Buildroot),在該路徑中,可以通過直接呼叫defconfig的形式進行快速配置,如:
make qemu_mips64el_malta_defconfig
配置完成後,需要調整部分選項資訊,則可以通過”make menuconfig”進入選單,進行修改。
這裡可以將預設的軟體包下載倉庫調整為Buildroot的備份倉庫,這樣可以加快下載速度,避免部分軟體包無法下載的情況。調整的配置路徑如下:
│ Symbol: BR2_PRIMARY_SITE [=http://sources.buildroot.net] │ │ Type : string │ │ Prompt: Primary download site │ │ Location: │ │ -> Build options │ │ -> Mirrors and Download locations 將該值設定為“http://sources.buildroot.net”
修改完配置後,即可通過ecs進行後退,到最後一層退出時提示儲存配置資訊,儲存即可。
編譯
在配置完成後,即可進入編譯步驟。編譯命令如下:
make source # 提前將軟體包全部下載,可省略 make # 進行編譯
上述編譯步驟中,”make source”是可以省略的。但是通過“make source”可以將編譯所需的全部軟體包進行下載,後續進行編譯即可,減少了編譯過程中由於軟體包無法下載導致的編譯暫停。“make source”可以不執行,這樣在編譯的過程中,需要編譯某個軟體包時再下載,也是可以的。
Buildroot可以“make”命令完成編譯,編譯完成後,在output目錄下存放著編譯結果。至此,全部操作結