建立編譯環境 (Cross Compiler)

建立基本的 OpenWRT 程式編譯環境

Cross Compiler 的建立

為了在 OpenWRT 上執行所設計的程式,我們需要建立 cross-compiler (toolchain) 來進行程式的編譯,為了建立此環境,我們選用 Ubuntu 12.04 以及 Ubuntu 16.04 作為 VM 的作業系統,並按照官網的步驟,建立 cross-compiler 的環境。詳細的步驟可以參考:

(1) 在安裝好 Ubuntu 的 VM 上,一開始先取消 SED 的功能

$ unset SED

(2) 安裝需要的程式

$ sudo apt-get install build-essential subversion git-core libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip

(3) 下載 OpenWRT 的環境。對於 AR300M 而言,這裡相對應的版本為15.05 branch (Chaos Calmer)。要注意的是,由於 Chaos Calmer 已不在主專案 (openwrt.git) 中, https://dev.archive.openwrt.org/wiki/GetSourcearrow-up-right 的指令是錯誤的。

$ git clone -b chaos_calmer git://github.com/openwrt/chaos_calmer.git

對於 AR750S,要下載 18.06 版的 OpenWRT,指令如下:

$ git clone git://github.com/openwrt/openwrt.git

由於一開始此操作文件是對 AR300M 製作,所以會以 Chaos Calmer 的版本為主。對於 AR750S 而言 (18.06),以下提及 chaos_clamer 的資料夾都會變成 openwrt,此資料夾的名稱和GIT專案中名稱一致。

circle-info

在使用 git 時,-b 指定不同的分支,而後面的網址代表不同專案。考慮到版本不斷演進,通常 openwrt.git 中只有最新的方案。

circle-info

[2022 更新] 18.06 版本的指令改成:

git clone -b openwrt-18.06 https://github.com/openwrt/openwrt.git

和之前指令有兩個差別: 加入 branch name, git 只支援 https

(4) 透過 git 取得 OpenWRT 的資料後,會產生一個相對應的資料夾 (chaos_calmer),在此,先更新 OpenWRT 的對應檔案:

circle-info

如果遇到下列錯誤:fatal: unable to access 'https://my.git.com:port/user_name/project.git/': server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none

可以使用指令:export GIT_SSL_NO_VERIFY=1

來源:https://cynthiachuang.github.io/Git-Https-Server-Certificate-Verification-Failed-Solution/arrow-up-right

(5) 接著,開始安裝 (make) 的準備

circle-info

Your display is too small to run Menuconfig!

It must be at least 19 lines by 80 columns.

make: *** [menuconfig] Error 1

這裡會一個錯誤訊息,似乎是VM的螢幕顯示尺寸問題,由於需要開起圖形化介面,當使用VirtualBox進行操作時,顯示的解析度無法調動。因此,設定介面無法正確顯示。

在這邊我的解決方案為透過putty登入該VM,方法為:

  1. 設定 NAT 網路,進行 port-port 的轉換。經過設定後,將12422 port 對應於 VM 的 22 port。

  2. 利用 putty 登入 VM (127.0.0.1:12422)。

Menuconfig的介面

這邊檢查了一下使用的晶片和 WiFi AP 所使用的晶片是否一致。在 OpenWRT 下查詢晶片內容的方法為: cat /proc/cpuinfo,透過指令,以AR-750S為例,我們可以看到如下的硬體資訊列表:

cat /proc/cpuinfo

在系統資訊中,最重要的就是晶片組的資訊,AR-750S使用沒 Qualcomm QCA956X 的晶片,此處的規格必須和上述 menuconfig 的 Target System 設定一致。

記得在 Build the OpenWrt SDK 的選項不要包含,此介面也可以用以編輯燒錄時要使用的 OpenWRT 映像檔,不過目前並未測試此功能。

circle-info

在安裝 OpenWRT 18.06 時,改用 Ubuntu 16.04 64bit 版本,就沒有顯示的問題,應該是 Ubuntu 12.04 的問題。只是要注意硬碟空間,在安裝時,我使用 20G 的硬碟空間,裝完後剩下不到 1G。使用 10G 的空間則會在make時出錯 (沒有足夠空間)。

(6) 執行 OpenWRT 的安裝,耗時數小時,安裝好占約 3GB 的硬碟空間 (chaos calmer)

此指會依序安裝不同的功能,安裝完後會顯示以下資訊:

(7) 完成後,cross-compiler 已經完成。在執行編譯前,我們需要預先宣告編譯環境,將 cross compiler 所在的資料夾加入 PATH 環境變數,將環境變數 STAGING_DIR 定義為資料夾 staging_dir 的所在路徑。指令如下:

circle-info

export PATH=$PATH:~/dir/這個指令是把之後的資料夾加入PATH的路徑中,也就是產生一個開啟的捷徑,讓我們可以在家目錄下開啟 mips compiler,每一次安裝好後,路徑可能都不太一樣,舉例來說,18.06的路徑為: ~/openwrt/staging_dir/toolchain-mips_24kc_gcc-7.3.0_musl/bin/。對於不同版本的安裝,記得用TAB檢查一下安裝目錄。

circle-info

這些設定每次重開機都必須重新執行。可以將此指令存入文件中,例如: initial_exp.sh。可以透過 source initial_exp.sh 來載入這些設定。或是寫入~/.bashrc 中,開機自動執行。

(8) 設定完成之後,在任意資料夾輸入 mips 之後,按兩下 TAB 鍵,應該會出現各種 cross-compiler,如下圖顯示:

mips cross-compiler

(9) 進行 hello_world 的簡單測試

編譯好的 hello_world 不能在 Ubuntu 上執行,但是可以在 OpenWRT 系統上執行。透過 winscp,我們可以將編譯好的檔案移到 OpenWRT 平台上執行,結果顯示於下圖中。

circle-info

Winscp 提供 Linux 和 Windows 之間的檔案傳送的圖形化介面,使用上只需要填入 IP 以及 port (通常為22),就可以透過圖形化介面傳輸檔案。請參考: https://winscp.net/eng/download.phparrow-up-right

AR750S上執行的成果
circle-info

考慮到 Linux 和 Windows 系統的差別,執行的權限會在搬移檔案後需要設定。最簡單的方法就是使用 # chmod 777 filename,直接賦予檔案執行的權限。若是想要知道關於執行權限的設定,可以參考: http://linux.vbird.org/linux_basic/0210filepermission.phparrow-up-right

package 的引入與環境建立

透過make menuconfig我們可以設定要額外編譯的 package,以 libnl-3 為例,我們可以從 Libraries 進入,並把相對應的 libnl package 勾選 (如下圖所示), 之後,再進行make

完成make之後,相對應的 package 出現於build_dir底下 (如下圖),其中,要引入的 header 檔位於include的資料夾內。

另一方面,編譯好的 .o/.a 檔則位於staging_dir資料夾中的usr/lib之下,透過取得 header 檔以及 .o/.a 檔的位置,我們就可以在進行 openwrt 程式開發時,引入額外的 package,進行較複雜的程式編譯。

circle-info

當使用 gcc 引入編譯好的 .o/.a 檔時,若出現以下錯誤: /home/ofwrt/openwrt/staging_dir/target-mips_24kc_musl/usr/lib/libnl-3.a: file not recognized: file truncated 代表編譯的時候出現一些問題,可以試著重新make openwrt一次,並清理 (make clean) 原有專案後,有機會可以消除此問題。

外部 package 的編譯

考慮到版本問題,有時候我們也需要從 source code 開始進行編譯,相同的這樣的過程需要透過 cross compile 進行,我們以 openssl-1.0.2 為例進行說明。

一開始,先下載相對應的程式碼,並解壓縮:

接著,把檔案移到staging_dir底下

進入openssl-1.0.2g資料夾下,並對其 config 檔進行設定:

其中,設定包含以下內容:

  • shared: 產生 .so 的動態函式庫

  • no-asm: 取消 asm 功能

  • setarch i386: 在 32 bit 環境下進行編譯

  • --cross-compile-prefix=mips-openwrt-linux- 使用 cross-compile 進行編譯

完成後,執行make,執行後應會產生檔案如下圖所示:

使用file檢查所產生的libssl.so.1.0.0.

可以看到,所產生的函示庫支援 mips 架構 (openwrt CPU 的計算架構)。若需要使用可以直接連接 .a 檔 (靜態函式庫),進行程式的開發。

Last updated