1. 程式人生 > 其它 >Hi3516EV200 編譯環境配置及交叉編譯軟體包

Hi3516EV200 編譯環境配置及交叉編譯軟體包

原文地址: Hi3516EV200 編譯環境配置及交叉編譯軟體包 - WindSpiritIT

基礎資訊

OS: Ubuntu 16.04 xenial

SDK 版本: Hi3516EV200R001C01SPC012 - Hi3516EV200_SDK_V1.0.1.1

SDK 包路徑:Hi3516EV200R001C01SPC012\01.software\board\Hi3516EV200_SDK_V1.0.1.2.tgz

開發板地址:192.168.1.54

開發板 MAC:7C:A7:B0:F6:E4:10

開發板 senser: GC2053

虛擬機器地址:192.168.1.141

目錄結構

下面的目錄樹列出了在整個配置流程中涉及的所有 SDK 和板端應用相關檔案和目錄的相對位置關係

~
├── ...
├── arm-himix100-linux  # 交叉編譯器
│   ├── ...
│   └── arm-himix100-linux.install  # 交叉編譯工具安裝指令碼
├── DPO_MT7601U_LinuxSTA_3.0.0.4_20130913   # MT7601U 驅動包
│   ├── ...
│   └── mcu
│       ├── ...
│       └── bin
│           ├── ...
│           └── MT7601.bin  # MT7601U 驅動韌體
├── Hi3516EV200_SDK_V1.0.1.2    # SDK 包
│   ├── ...
│   ├── mpp
│   │   ├── ...
│   │   ├── ko  # 板端 ko 庫目錄
│   │   │   ├── ...
│   │   │   ├── hi3516ev200_base.ko
│   │   │   ├── hi3516ev200_isp.ko
│   │   │   ├── hi3516ev200_ive.ko
│   │   │   ├── load3516ev200   # ko 庫載入指令碼
│   │   │   └── sys_config.ko
│   │   └── sample  # 示例專案目錄
│   │── osdrv
│   │   ├── ...
│   │   ├── opensource
│   │   │   ├── ...
│   │   │   └── kernel
│   │   │       ├── ...
│   │   │       └── linux-4.9.y # linux 核心原始碼
│   │   │           ├── ...
│   │   │           ├── arch
│   │   │           │   ├── ...
│   │   │           │   └── arm
│   │   │           │       ├── ...
│   │   │           │       └── boot
│   │   │           │           ├── ...
│   │   │           │           └── uImage  # 單獨構建的 kernel 映象
│   │   │           └── firmware
│   │   │               ├── ...
│   │   │               └── mt7601u.bin     # MT7601U 驅動韌體
│   │   └── pub
│   │       ├── ...
│   │       ├── hi3516ev200_spi_image_uclibc    # osdrv 構建目標目錄
│   │       │   ├── ...
│   │       │   ├── rootfs_hi3516ev200_64k.jffs2    # SPI Nor 檔案系統映象
│   │       │   ├── u-boot-hi3516ev200.bin          # fastboot 映象
│   │       │   └── uImage_hi3516ev200              # linux kernel 映象
│   │       ├── rootfs_uclibc_64k_custom.jffs2    # 單獨構建的 SPI Nor 檔案系統映象
│   │       ├── rootfs_uclibc       # 檔案系統目錄
│   │       │   ├── ...             # 以下列出將要新增到檔案系統中的檔案
│   │       │   └── etc
│   │       │       ├── ...
│   │       │       ├── init.d
│   │       │       │   ├── ...
│   │       │       │   ├── S80wireless     # 自行建立的無線網路初始化指令碼
│   │       │       │   └── rcS             # 檔案系統初始化指令碼
│   │       │       ├── ...
│   │       │       └── wpa_supplicant.conf
│   │       └── rootfs_uclibc.tgz   # 檔案系統包
│   ├── sdk.cleanup     # osdrv 打包指令碼
│   └── sdk.unpack      # osdrv 解包指令碼
├── lrzsz-0.12.20   # lrzsz 原始碼
│   ├── ...
│   └── _install    # 構建目標目錄
│       ├── ...
│       └── bin
│           ├── ...
│           ├── lrz
│           └── lsz
├── osdrv_packages  # 用於構建 osdrv 的原始碼包
└── wpa_supplicant  # 構建 wpa_supplicant 應用原始碼及其依賴庫原始碼
    ├── dbus-1.13.20    # dbus 原始碼
    ├── expat-2.4.3     # expat 原始碼
    ├── install         # 構建目標目錄
    │   ├── dbus
    │   ├── libexpat
    │   ├── libnl
    │   ├── libssl
    │   └── wpa_supplicant
    │       └── usr
    │           └── local
    │               └── sbin
    │                   ├── wpa_cli
    │                   ├── wpa_passphrase
    │                   └── wpa_supplicant
    ├── libnl-3.5.0             # libnl 原始碼
    ├── openssl-1.1.1m          # openssl 原始碼
    └── wpa_supplicant-2.10     # wpa_supplicant 原始碼

切換為 bash

執行 sudo dpkg-reconfigure dash 選擇 NO

Ubuntu 預設使用 dash 作為 shell,SDK 中大部分指令碼基於 bash 編寫,這裡需要手動切換,否則可能出現 指令碼無法執行無法獲取變數導致遞迴修改根目錄許可權

編譯 osdrv

安裝依賴包

sudo apt install libncurses5-dev make libc6 lib32z1 lib32stdc++6 zlib1g-dev ncurses-term libncursesw5-dev g++ u-boot-tools liblzo2-dev uuid-dev pkg-config texinfo texlive gperf bison gawk curl upx pngquant flex libnl-3-dev libdbus-1-dev

解壓交叉編譯工具包並安裝

tar zxvf arm-himix100-linux.tgz
chmod +x arm-himix100-linux/arm-himix100-linux.install
cd arm-himix100-linux && ./arm-himix100-linux.install && cd ..

執行 SDK 目錄下 sdk.unpack

根據 osdrv/readme_cn.txt 目錄所述下載原始碼包並移動至指定目錄下,或執行打包好的 osdrv_packages 中的 cp_packages.sh 指令碼(暫不提供下載地址)

進入開發包中 osdrv 目錄下,開始編譯,不要在 make all 命令後使用 -j 選項,有可能因執行順序不同編譯失敗

cd osdrv
make all

Makefile 中使用了大量 >/dev/null 2>&1 重定向標準及錯誤輸出,導致編譯或配置過程出現錯誤時無法定位錯誤位置或解決方案,如果出現編譯失敗的情況請找到距離報錯處最近的一條編譯命令並手動編譯,定位錯誤

按照以上步驟編譯好 SDK 後目錄結構應如下所示

Hi3516EV200_SDK_V1.0.1.1
 ├─ drv
 ├─ mpp
 ├─ osal
 ├─ osdrv
 ├─ package
 ├─ scripts
 ├─ sdk.cleanup
 └─ sdk.unpack

其中 mpp 目錄用於存放初始化板端環境的指令碼以及執行庫

osdrv 目錄用於存放編譯好的分割槽映象及相關工具,結構如下

osdrv
├── Makefile
├── opensource
├── pub
│   ├── bin
│   │   ├── board_uclibc
│   │   └── pc
│   ├── hi3516ev200_spi_image_uclibc
│   │   ├── rootfs_hi3516ev200_128k.jffs2
│   │   ├── rootfs_hi3516ev200_256k.jffs2
│   │   ├── rootfs_hi3516ev200_2k_128k_32M.ubifs
│   │   ├── rootfs_hi3516ev200_2k_24bit.yaffs2
│   │   ├── rootfs_hi3516ev200_2k_4bit.yaffs2
│   │   ├── rootfs_hi3516ev200_4k_24bit.yaffs2
│   │   ├── rootfs_hi3516ev200_4k_256k_50M.ubifs
│   │   ├── rootfs_hi3516ev200_4k_4bit.yaffs2
│   │   ├── rootfs_hi3516ev200_64k.jffs2
│   │   ├── u-boot-hi3516ev200.bin
│   │   └── uImage_hi3516ev200
│   └── rootfs_uclibc.tgz
├── readme_cn.txt
├── readme_en.txt
├── rootfs_scripts
└── tools

編譯後會產生多個 rootfs 映象,我們可以先只燒錄 u-boot 映象後直接啟動

根據日誌中 SPI NorNAND 項的值來判斷 Flash 型別

其中 Nand 映象命名規則為 rootfs_hi3516ev200_{PageSize}_{EccType}.yaffs2

Nor 映象命名規則為 rootfs_hi3516ev200_{BlockSize}.jffs2

我手中的 Hi3516EV200 使用 Nor 格式,根據類似如下日誌可知 BlockSize 為 64KB

Block:64KB hifmc_spi_nor_probe(1706): Chip:32MB hifmc_spi_nor_probe(1707): Name:"MX25L(256/257)XX"
SPI Nor total size: 32MB

串列埠除錯

有些開發闆闆封裝了 TTL 介面,直接按定義連線即可

另一種型號的開發板沒有封裝 TTL 介面,但預留了孔位,在開發板 Hi3516 ERNCV200 晶片臨近板邊緣的一側 預留了兩個過孔,其中 靠近晶振一側 的過孔為 TX,接 USB-TTL 板 RX;另一側為 RX,接 USB-TTL 板 TX,地線可以直接接在 開發板四腳的過孔

安裝 USB-TTL 板晶片對應驅動後即可通過串列埠進入開發板終端,例如 CP210xCH340

編譯 lrzsz

lrzsz 可以通過串列埠或 telnet 等途徑傳輸小檔案

lrzsz

wget https://ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz
tar zxvf lrzsz-0.12.20.tar.gz
cd lrzsz-0.12.20
CC=arm-himix100-linux-gcc ./configure --host=arm-himix100-linux --build=arm-himix100-linux --prefix=$PWD/_install --cache-file=./arm-himix100-linux.cache
make -j12
make install

_install/bin/lrz
_install/bin/lsz

Telnet

手動執行或在板端檔案系統 /etc/init.d/rcS 中寫入如下命令即可

telnetd &

燒寫系統

開啟 HiTool 工具,通過串列埠連線開發板,將傳輸方式更改為串列埠,使用按分割槽燒寫,按照如下分割槽配置燒寫映象

串列埠燒寫需要進入 boot,所以開始燒寫前需要將開發板下電,點選燒寫按鈕開始燒寫後在 15 秒內上電

分割槽名 偏移 長度 檔名 器件型別 檔案系統
fastboot 0 (0M) 80000 (1M) u-boot-hi3516ev200.bin spi nor none
kernel 100000 (1M) 400000 (4M) uImage_hi3516ev200 spi nor none
rootfs 500000 (5M) 1b00000 (27M) rootfs_hi3516ev200_64k.jffs2 spi nor none

配置啟動引數

在 HiTool 中開啟終端工具,使用串列埠連線開發板

分割槽映象燒寫完成後會自動執行 reset 命令從 u-boot 重啟系統,但由於沒有配置啟動引數導致系統只能進入 u-boot,無法進入系統

  • u-boot 模式下終端格式為 hisilicon #,進入系統後格式為 路徑 #
  • 在 u-boot 終端下輸入如下命令,引數根據燒寫的映象以及實際需求進行配置
  • 開發板的記憶體分為兩種,一種是 OS Memory,一種是 MMZ Memory;開發板記憶體的管理機制為從總記憶體中減去 OS Memory,剩下的分配給 MMZ,而開發板推送視訊流等服務需要佔用一定 MMZ Memory。
  • 使用 setenv 命令設定系統變數後需要在重啟前使用 saveenv 儲存,否則所有更改在重啟後都會丟失
  • 啟動引數中的檔案系統型別、分割槽名以及分割槽長度需要與 HiTool 中燒寫時設定一致,否則在啟動時會找不到分割槽
setenv bootargs 'mem=32M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 rw mtdparts=hi_sfc:1M(boot),4M(kernel),27M(rootfs)'
setenv bootcmd 'sf probe 0;sf read 0x42000000 0x100000 0x400000;bootm 0x42000000'
saveenv
reset

基於 MT7601U 連線無線網路

本文中使用 wpa_supplicant 操作無線網絡卡,該工具依賴 libssl libnl libexpat dbus

libssl

OpenSSL

wget https://www.openssl.org/source/openssl-1.1.1m.tar.gz
tar zxvf openssl-1.1.1m.tar.gz
cd openssl-1.1.1m
./config no-asm no-shared no-async --prefix=$PWD/../install/libssl --cross-compile-prefix=arm-himix100-linux-

刪除 Makefile 中所有 -m64 選項

make -j12
make install

libnl

libnl

wget https://github.com/thom311/libnl/releases/download/libnl3_5_0/libnl-3.5.0.tar.gz
tar zxvf libnl-3.5.0.tar.gz
cd libnl-3.5.0
./configure --host=arm-himix100-linux --prefix=$PWD/../install/libnl --enable-static
make -j12
make install

libexpat

libexpat

wget https://github.com/libexpat/libexpat/releases/download/R_2_4_3/expat-2.4.3.tar.gz
tar zxvf expat-2.4.3.tar.gz
cd expat-2.4.3
./configure --prefix=$PWD/../install/libexpat --host=arm-himix100-linux --enable-shared --enable-static
make -j12
make install

dbus

dbus

wget https://dbus.freedesktop.org/releases/dbus/dbus-1.13.20.tar.xz
tar xvf dbus-1.13.20.tar.xz
cd dbus-1.13.20
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$PWD/../install/libexpat/lib/pkgconfig/
./configure --prefix=$PWD/../install/dbus --host=arm-himix100-linux --enable-shared --enable-static CFLAGS=-I$PWD/../install/libexpat/include LDFLAGS=-L$PWD/../install/libexpat/lib --disable-tests
make -j12
make install

wpa_supplicant

wpa_supplicant

wget http://w1.fi/releases/wpa_supplicant-2.10.tar.gz
tar zxvf wpa_supplicant-2.10.tar.gz
cd wpa_supplicant-2.10/wpa_supplicant
cp defconfig .config

將以下程式碼加入 .config

CFLAGS += -I../../install/libssl/include
LIBS   += -L../../install/libssl/lib

CFLAGS += -I../../libnl-3.5.0/include/linux-private
CFLAGS += -I../../install/libnl/include
CFLAGS += -I../../install/libnl/include/libnl3
LIBS   += -L../../install/libnl/lib

CFLAGS += -I../../install/dbus/include
LIBS   += -L../../install/dbus/lib

LDFLAGS += -pthread

CC = arm-himix100-linux-gcc

開啟 Makefile 並分別找到 wpa_cli wpa_passphrase wpa_supplicant 的編譯選項,在其編譯命令後新增 -static 以使用靜態連結庫

例如找到 wpa_supplicant 的編譯選項如下

wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
        $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
        @$(E) "  LD " $@

將其修改為

wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
        $(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS) -static
        @$(E) "  LD " $@

編譯應用

make -j12
make install DESTDIR=$PWD/../../install/wpa_supplicant

使用 arm-himix100-linux-strip 命令裁剪應用

wpa_cli wpa_passphrase wpa_supplicant 複製到檔案系統,並在檔案系統 etc 目錄下建立 wpa_supplicant.conf 檔案並寫入如下配置

ctrl_interface=/var/run/wpa_supplicant
update_config=1

連線 WiFi

以下為板端配置

開啟網絡卡配置網路並啟動 wpa_supplicant,其中 MAC 地址、裝置 IP 地址及路由地址請 根據實際情況配置

ifconfig wlan0 up
ifconfig wlan0 hw ether 7C:A7:B0:F6:E4:10
ifconfig wlan0 192.168.1.54 netmask 255.255.255.0
route add default gw 192.168.1.1
wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.conf -B

wpa_cli -i wlan0 進入互動命令,互動命令列中退格使用 Ctrl + Backspace

# 搜尋 WiFi
scan
# 輸出搜尋結果
scan_result

# [WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS]
set_network 0 ssid "name"
set_network 0 psk "psk"
enable_network 0

# [None]
set_network 0 ssid "name"
set_network 0 key_mgmt NONE
enable_network 0

# 儲存
save_config
# 關閉連線
disable_network 0
# 列出所有儲存的連線
list_network
# 選擇第一個儲存的連線
select_network 0
# 連線第一個儲存的連線
enable_network 0

將以上步驟整理成自動化指令碼寫入板端檔案系統 /etc/init.d/S80wireless 並使用 chmod +x S80wireless 賦予執行許可權

#!/bin/sh
wlandev=wlan0
phyaddr=7C:A7:B0:F6:E4:10
ipaddr=192.168.1.54
netmask=255.255.255.0
gateway=192.168.1.1

ifconfig $wlandev up
ifconfig $wlandev hw ether $phyaddr
ifconfig $wlandev $ipaddr netmask $netmask
route add default gw $gateway
wpa_supplicant -D nl80211 -i $wlandev -c /etc/wpa_supplicant.conf -B

板端開機後執行一次 wpa_passphrase "ssid" "psk" >> /etc/wpa_supplicant.conf 重啟即可自動連線

MT7601U Driver

DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tgz

linux kernel 載入韌體分為兩種途徑

  • 讀取檔案系統 /lib/firmware 目錄下韌體
  • 將韌體整合進 linux kernel

第一種方法由於掛載檔案系統在網絡卡載入韌體之後,故不可行,這裡選擇將韌體整合進 kernel

將韌體 DPO_MT7601U_LinuxSTA_3.0.0.4_20130913/mcu/bin/MT7601.bin 複製到 kernel 原始碼中 firmware 目錄下並重命名為 mt7601u.bin

對 kernel 執行 menuconfig 結束生成 .config 配置後,在該檔案中修改 CONFIG_EXTRA_FIRMWARE 的值為空格分隔的韌體名,例如 CONFIG_EXTRA_FIRMWARE="a.bin b.bin",並新增 CONFIG_EXTRA_FIRMWARE_DIR="firmware"

修改完成後應如下所示

CONFIG_EXTRA_FIRMWARE_DIR="firmware"
CONFIG_EXTRA_FIRMWARE="mt7601u.bin"

kernel with MT7601U support

osdrv/opensource/kernel/linux-4.9.y

make ARCH=arm CROSS_COMPILE=arm-himix100-linux- menuconfig
# Networking support —> Wireless
# <*>   cfg80211 - wireless configuration API
# <*>   Generic IEEE 802.11 Networking Stack (mac80211)
# Networking support —> RF switch subsystem support
# <*>   GPIO RFKILL driver
# Device Drivers —> Network device support -> Wireless LAN
# [*]   MediaTek devices
# <*>     MediaTek MT7601U (USB) support
# <*>     IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)
# [*]       Support downloag firmware images with Host AP driver
# [*]         Support for non-volatile firmware download
make ARCH=arm CROSS_COMPILE=arm-himix100-linux- uImage -j12

rootfs with custom files

osdrv/pub

tar zxvf rootfs_uclibc.tgz
./bin/pc/mkfs.jffs2 -d rootfs_uclibc -l -U -e 0x10000 -o rootfs_uclibc_64k_custom.jffs2
# -d    Build file system from directory DIR
# -l    Create a little-endian filesystem
# -e    Use erase block size SIZE   0x10000 = 64KB
# -o    Output to FILE

使用 NFS 掛載伺服器目錄

搭建 NFS 伺服器

該步驟所有操作均位於虛擬機器端

安裝 NFS 服務端

sudo apt install nfs-kernel-server

將需要通過 NFS 共享的目錄按下面格式寫入 /etc/export

其中 IP 地址用於限制只允許指定 IP 掛載訪問 NFS,可以使用類似 192.168.1.*192.168.1.0/24 的寫法

/path/to/nfs/dir 192.168.1.54(rw,sync,no_root_squash,no_subtree_check)

匯出共享目錄並重啟 NFS 服務

sudo exportfs -a
sudo systemctl restart nfs-server

固定埠及開放防火牆

若需要為虛擬機器設定防火牆,需要配置 NFS 相關服務使用固定埠

sudo sed -i 's/RPCMOUNTDOPTS="--manage-gids"/RPCMOUNTDOPTS="--manage-gids -p 30001"/' /etc/default/nfs-kernel-server
sudo touch /etc/modprobe.d/options.conf
sudo tee -a /etc/modprobe.d/options.conf >/dev/null << EOF
options lockd nlm_udpport=40002
options lockd nlm_tcpport=40002
EOF
sudo tee -a /etc/modules >/dev/null << EOF
lockd
EOF

開放防火牆以 firewalld 為例

sudo firewall-cmd --zone=public --add-port=111/tcp --add-port=111/udp --add-port=2049/tcp --add-port=2049/udp --add-port=30001-30002/tcp --add-port=30001-30002/udp --permanent
sudo firewall-cmd --reload

重啟後即可生效

板端掛載 NFS

該步驟所有操作均位於板端

將虛擬機器中 NFS 掛載到 /mnt 目錄

mount -t nfs -o nolock -o tcp -o rsize=32768,wsize=32768 192.168.1.141:/path/to/nfs/dir /mnt

配置板端環境變數

將以下配置寫入 /root/.profile,用於啟動板端 PQ 工具

其中板端 PQ 工具位於 SDK 目錄下 Hi3516EV200R001C01SPC012\01.software\pc\PQTools\Hi3516EV200_PQ_V1.0.1.2.tgz

具體路徑請根據實際情況修改

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/mpp/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/Hi3516EV200_PQ_V1.0.1.2/libs