---
# System prepended metadata

title: Useful Tips in Emebeded Linux Devlopment
tags: [linux kernel, Embedded Linux, Useful tips, initrd.img, u-boot, beaglebone black]

---

# Useful Tips in Emebeded Linux Devlopment
持續更新...
最近更新日期:2020.03.31
[TOC]

## Beaglebone Black的參考網站(AM335x)
以下三個我覺得相當有用
- [Linux on Arm](https://www.digikey.com/eewiki/display/linuxonarm/BeagleBone+Black)
裡面有u-boot/linux kernel/rootfs的資源
- [elinux.org](https://elinux.org/Beagleboard:BeagleBoneBlack_Debian)
這個頁面有各種的Beaglebone black image可以使用，可以把xz解開後直接使用其img，掛載為loop device去修改其內容
- [TI Website for AM335x](http://www.ti.com/tool/PROCESSOR-SDK-AM335X)
這個頁面就是TI對於AM335X系列SoC的軟體開發支援，像是BSP/Toolchain都可以在這邊下載。

## 好用的系統指令
主要環境都在Debian Distribution試過
### 列出系統服務 
> systemctl list-unit-files
> 或是
> systemctl list-unit --type service
> 或是
> systemctl | grep YOUR_SERVICE_NAME
> 或是
> cat /etc/services | more
### 列出網路服務
列出網路服務:列出目前針對網路的服務/IP位址/埠號/網路介面
> 要用netstat必須要先安裝net-tools
> sudo apt install net-tools
> netstat -pnltu
### TCPDump for bootp
tcpdump -v -n -i INTERFACE-NAME port bootps(bootp server)
tcpdump -v -n -i INTERFACE-NAME port bootpc(bootp client)
### 修改hostname/hosts
修改/etc/hostname
就是修改device名稱
同時也要修改/etc/hosts
內容新增
> 127.0.0.1 YOUR_DEFINED_HOSTNAME

### 修改sudoer PATH
由於在使用sudo時，shell環境會切回預設的PATH，所以如果自己在/etc/profile.d的目錄下有修改PATH的話，也要一併在/etc/sudoer下修改PATH
新增以下內容
> Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
> ##後面可以是自己定義新增PATH
### LD_LIBRARY_PATH的運用與取代
可以在rcS.d或是profile.d去export這個變數，讓shared library可以多一個地方去關聯。
另外由於setuid/setgid的屬性被設起來的執行檔，基於安全性的考量，LD_LIBRARY_PATH會被忽略而不會加入執行檔的LD PATH中，因此另外的解法就是在compile time使用
> export LDFLAGS="-R**YOUR_LIB_PATH**"
### Samba服務設定
目前Samba(V4.11.6)版本，除了編輯/etc/samba/smb.conf之外，還需要使用
> net usershare add SHARE_TAG SHARE_PATH

的命令去讓share生效
先設定samba
```settings=
## /etc/samba/smb.conf
## SHARE_TAG is tftpboot
[tftpboot]
    comment = tftpboot_folder
    path = /tftpboot
    browseable = yes
    writable = yes
    read only = no
    create mask = 0766
    directory mask = 0766
    guest ok  = yes
    valid users = SMB_USER_ACCOUNT
```
新增一個samba user
> sudo smbpasswd -a SMB_USER_ACCOUNT
 
新增usershare
> net usershare add tftpboot /tftpboot
 
這樣就可以分享檔案了。

## 使用systemd新增服務
Ref: [systemd參考文件](https://wiki.archlinux.org/index.php/Systemd_(%E6%AD%A3%E9%AB%94%E4%B8%AD%E6%96%87))
systemd的單元檔案(Unit file)是systemd會去讀取來啟動服務的設定檔，載入的路徑由低到高會是
- /usr/lib/systemd/system : 軟體包安裝的路徑
- /etc/systemd/system : 系統管理員安裝的路徑

另外，不要在unit file裡面使用行內註釋
### 新增Unit file
Unit file通常用來
- 處理依賴關係:以標籤[Unit]開始的區段，使用After/Requires來決定服務先後關係
- 定義服務類型:以標籤[Service]開始的區段，有以下設定
    - ==Type=simple(預設值)==:立即啟動服務，而且不會fork該服務，若該服務是要啟動其他服務的話，就不要選simple
    - ==Type=forking==: 可以fork並呼叫其他程序，需要指定==PIDFile\===，讓systemd可以跟蹤服務的主程序
    - ==Type=oneshot==:適合執行完任務立刻退出的服務，可能需要同時設定==RemainAfterExist=yes==，使得systemd在服務程序退出後仍認為服務是activate
    - ==Type=notify==:與simple相同，但是會在服務啟動後向systemd發送一個signal
    - ==Type=dbus==:這方式啟動需要指定==BusName==，當那個D-Bus系統Ready時systemd就會知道其服務就緒了
    - ==Type=idle==:等到所有工作處理完後<才會執行idle類型的服務，是優先順序最低的，但啟動行為和simple類似
    
- 定義目標:
    - runlevel0.target, poweroff.target: 停機，關閉系統
    - runlevel1.target, rescue.target: 單使用者模式
    - runlevel2.target, runlevel4.target, multi-user.target:用戶自訂啟動級別，預設繼承級別3
    - runlevel3.target, multi-user.target: 多使用者，無圖形介面，使用者可以由終端或是網路登入
    - runlevel5.target, graphical.target: 多使用者，圖形介面，繼承級別3服務，並可以啟動圖形介面服務
    - runlevel6.target, reboot.target: 重新開機
    - emergency.target: 急救模式(Emergency shell)

Porting的最快方式，先在Host PC用package安裝，然後再把ㄇpackage安裝的XXX.service內容弄到target的/etc/systemd/system/XXX.service

每個系統的設定有點不同，像是debian，它會在/lib/systemd/sytem/XXX.service

而/etc/systemd/system則是存放其symbolic link而已，如果它是multi-user.target.wants的話，就要建立兩個symbolic link:
* 在/etc/systemd/system/XXX.service
* 在/etc/systemd/system/multi-user.target.wants/XXX.service
以下就是一個lighttpd webserver的啟動單元檔
```setting
[Unit]
Description=Lighttpd Daemon
After=network.target

[Service]
Type=simple
ExecStartPre=/home/conch/conch_service/sbin/lighttpd -tt -f /home/conch/conch_service/etc/lighttpd/lighttpd.conf
ExecStart=/home/conch/conch_service/sbin/lighttpd -D -f /home/conch/conch_service/etc/lighttpd/lighttpd.conf
Restart=on-failure

[Install]
WantedBy=multi-user.target

```
### 服務啟動/檢查/停止的指令
- 啟動: **sudo systemctl start YOUR_SERIVCE_NAME**
- 再啟動: **sudo systemctl restart YOUR_SERVICE_NAME**
- 停止: **sudo systemctl stop YOUR_SERVICE_NAME**
- 確認服務狀態: **systemctl status YOUR_SERVICE_NAME**

### 找尋smb連結的資料匣
/run/user/**USER_ID**/gvfs/
## Edit UEFI menu on PC/NB
[source](https://askubuntu.com/questions/63610/how-do-i-remove-ubuntu-in-the-bios-boot-menu-uefi)
這一段主要是針對要用來開發embedded Linux的Host PC/NB開機系統選項所做的設定
You should be able to do this via a Live Ubuntu CD.(or SD card of boot iso burned-in via usb sd card reader)

Install efibootmgr:(has already pre-installed on ubuntu 18.04 boot device)

>sudo apt-get install efibootmgr
>
Then add to the kernel efi support

> sudo modprobe efivars
> 
Then run sudo efibootmgr to check your boot entries. It will return something like this:

>BootCurrent: 0004
>Timeout: 2 seconds
>BootOrder: 2001,0003,0005,0006,0000
>Boot0000* Lenovo Recovery System
>Boot0001* EFI Network 0 for IPv6 (B8-88-E3-84->F3-EF)
>Boot0002* EFI Network 0 for IPv4 (B8-88-E3-84->F3-EF)
>Boot0003* Windows Boot Manager
>Boot0004* EFI USB Device (SanDisk)
>Boot0005* ubuntu
>Boot2001* EFI USB Device

Then delete the option you dont want. In this example, Ubuntu is entry 5. the following could be called to delete entry 5 and remove it from the BootOrder.

(CAUTION: Before executing the following command make sure you enter the correct Boot entry number)

>sudo efibootmgr -b 5 -B
>
Further details described here: http://linux.die.net/man/8/efibootmgr

Note: as for anything that changes your bootloader, please ensure you have a good disk image that you can boot with.

Now you should also delete the ubuntu subdirectory in the EFI partition to prevent the UEFI firmware from restoring the entry into the BootOrder.

To do that, first find your EFI partition. Run **sudo fdisk -l** to see the partitions on all attached drives. The EFI partition has **EFI Partition** under the Type column.

Suppose your EFI partition was /dev/sda2, then mount it on an empty folder anywhere.

>    sudo mkdir /mnt/efipart
>    sudo mount /dev/sda2 /mnt/efipart
>    
Now we have to find the directory Ubuntu or any other distro's name in this partition. It is mostly under EFI/distro_name.

Remove that directory and its contents by (PLEASE MAKE SURE YOU ARE DELETING THE CORRECT DIRECTORY) **sudo rm -r ubuntu.**
## Beaglebone Black設定網路
### Beaglebone Black設定Static IP Address(with connman)
由於BBB並不吃/etc/network/interfaces的設定，而是connman的設定，所以利用以下指令取得目前的Config name
> connmanctl services
> 
取得Config name之後使用以下指令
```shell=
sudo connmanctl config  <service> --ipv4 manual <ip_addr> <netmask> <gateway> --nameservers <dns_server>
```
其實是把設定檔放在/var/lib/connman/下面

### Beaglebone Black設定Static IP Address(without connman)

[Reference](http://variwiki.com/index.php?title=Static_IP_Address)

由於有些BBB的image是用yocto project去產生出來的
而yocto project所產生出來的image預設是用connman去管理網路而不是/etc/network/interfaces(即使你設定了connman也會override)

因此可以用以下步驟來讓系統網路讓/etc/network/interfaces生效(以ethernet為例)

1. 編輯/etc/connman/main.conf
在內容[General]標籤下新增blacklist
> [General]
> NetworkInterfaceBlacklist=eth0,eth1

2. 編輯/etc/network/interfaces
在內容加入以下例子
```config
 auto eth0
    iface eth0 inet static
    address 192.168.0.123
    netmask 255.255.255.0
    gateway 192.168.0.1
    dns-nameservers 192.168.0.1 8.8.8.8 4.4.4.4
```
另外，如果沒有/sbin/resolvconf，interfaces的nameserver是不會起作用的。

這時候就要去修改rootfs/etc/init.d/connman這個script，把/etc/resolv.conf和/run/connman/resolv.conf的關聯取消掉
```bash=
##修改rootfs/etc/init.d/connman
## mark掉下面區段的code
if [ "CONNMAN_RUNSTATEDIR_RESOLVCONF" != "no" ] ; then
    mkdir -p /run/connman
#marked    ln -sf /run/connman/resolv.conf /etc/
fi
```
自己另外寫一個/etc/resolv.conf，內容可以像是
> \### /etc/resolv.conf by default settings
> nameserver 192.168.0.1
> nameserver 8.8.8.8
> nameserver 8.8.4.4


## Linux Account Management
### add user
> sudo adduser USERNAME
### delete user
> sudo userdel USERNAME
### modify user
> sudo usermod USERNAME
> -aG 後面可以加GROUPNAME，如果有一堆Group，就使用逗號隔開
### add user to group
> sudo usermod -a -G GROUP_NAME USER_NAME
## Mount file as block device
先假設file名稱是sd.img
- 掛載檔案到/dev
> sudo losetup -f --show sd.img
> 指令下完會顯示掛到哪個device
- 卸載檔案
> sudo losetup -d /dev/loop0
- 掛載Image file partition
> sudo kpartx -va sd.img
- 卸載Image file partition
> sudo kpartx -d sd.img

## Modify Linux Kernel Image Version
要停止script去自動生成Git version的字串到Linux kernel主要是要設定menuconfig裡面的參數
> CONFIG_LOCALVERSION_AUTO
> 把它設n或是not set
> 這個參數在執行menuconfig的時候，在General Config裡面可以設定

設為N或是另外要修改的地方是Kernel source folder下的scripts/setlocalversion
改兩個地方echo "+"和scm:++
```bash
# If only the short version is requested, don't bother
# running further git commands
if $short; then
#marked this line             echo "+"
    return
...
...
if test "${LOCALVERSION+set}" != "set"; then
                scm=$(scm_version --short)
#marked this line    res="$res${scm:++}"

```
另外一個地方就是include/config/kernel.release裡面Kernel資訊
## Kernel Ram Disk Creation: initrd.img-VERSION
### 準備
- 前一版本的initrd.img-{KERNEL_VERSION}
- 已經build好的linux kernel source folder
### 處理前一版本的initrd.img-{KERNEL_VERSION}
In your working folder, if it was named initrd
> mv initrd.img-{KERNEL_VERSION} initrd.img.gz
> gunzip initrd.img.gz | cpio -idm

這時候你會得到解壓縮的initrd.img，也就是ram rootfs

### 製作新版本的initrd.img-{NEW_KENEL_VERSION}
- 把上一節initrd目錄裡面的東西除了initrd.img外拷貝到kernel source folder裡面的rootfs(名稱是甚麼可以自己訂)
- 把自己在build kernel時候install的module安裝到rootfs/lib/modules/{new_kernel_version}的目錄，並記得把rootfs/lib/modules/{old_kernel_version}的kernel module給刪掉
- 執行以下指令(kernel source folder下)
```bash=
 ./usr/gen_initramfs_list.sh rootfs/ > filelist
 ./usr/gen_init_cpio filelist > init.img
 gzip init.img
 mv init.img.gz init.img-{KERNEL_VERSION}
```
最後的成果就是init.img-{KERNEL_VERSION}，把它拷到target board image的rootfs/boot裡面，並且搭配先前自己build好的kernel image
## 設定自己toolchain的路徑
可以到/etc/profile.d目錄下面設定自己的sh檔，譬如以開發Beaglebone black的板子來說，可以在profile.d下面創建一個ti.sh，檔案內容就可以是
> export PATH=$PATH:/usr/local/arago-2019.07/sysroots/x86_64-arago-linux/usr/bin

可以注意到的是，我把toolchain的路徑直接拉到PATH最後面，這是為了防止toolchain裡面有其他的如git的application，而這也會導致一些系統安裝的application會不正常運作。

## 燒錄U-boot的dd命令
這個是Sd card
> export DISK=/dev/mmcblk0

這個是燒MLO
> sudo dd if=./u-boot/MLO of=${DISK} count=1 seek=1 bs=128k

這個是燒u-boot.img

> sudo dd if=./u-boot/u-boot.img of=${DISK} count=2 seek=1 bs=384k
## 安裝JDK for Beaglebone black
AM335x主要是用armhf版本的java
在這邊是使用[jdk-8u241-linux-arm32-vfp-hflt.tar.gz](https://drive.google.com/file/d/1wcrKf2Upl5DdgTajBv1jG1YA72g2iK9x/view?usp=sharing)
把內容解壓縮到BBB的/usr/local
**tar zxvf jdk-8u241-linux-arm32-vfp-hflt.tar.gz**
解開的資料匣會是jdk1.8.0_241
去/etc/profile.d/*.sh的檔案裏面
把PATH加上
**/usr/local/jdk1.8.0_241/bin**
並且export JAVA_HOME
**export JAVA_HOME=/usr/local/jdk1.8.0_241/bin/java**
重新開機後就OK了
在命令列下會獲得以下資訊
> $ java -version
> java version "1.8.0_241"
> Java(TM) SE Runtime Environment (build > 1.8.0_241-b07)
> Java HotSpot(TM) Client VM (build 25.241-b07, mixed mode)
這樣算是安裝完了。
## 手動編譯Python 3(HOST PC)
### 準備 & 環境
環境: Ubuntu 18.04
- 下載Python 3.8.2 (stable release, 2020-02-24)
    [Python 3.8.2 source code](https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tgz)
- 安裝zlib1g-dev與其他套件
```shell=
sudo apt-get install build-essential checkinstall
sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
    libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev
```
### 編譯與安裝
- 解壓縮
    $ sudo tar xzf Python-3.8.2.tgz
- 設定
    sudo ./configure --enable-optimizations
- 編譯與安裝
    $ sudo make altinstall
    altinstall可以避免binary file安裝到/usr/bin/python
- 確定 Python版本
    $ python3.8 -V
## Cross Compiling Python 3.8 (for Beaglebone Black)
### 準備
- 安裝Python 3.8(Host PC)
- 編譯ARM版本libffi
- 安裝Python 3.8 pgen
    - 安裝方式: Python3.8.2 source code folder下
    ```script=
    make distclean
    ./configure
    make python Parser/pgen
    ```
    build完就會在souce folder 下面的Parser/pgen folder下面，把它(Parser/pgen)拷到/usr/local/bin下面(和python3.8 binary同一個folder)

### 編譯與安裝
```script=
#!/bin/bash
# build for embedded device: am335x/beaglebone black
# source code is python 3.8.2
CROSS_COMPILER_PREFIX=arm-linux-gnueabihf-
CROSS_COMPILER_HOST=arm-linux-gnueabihf

make distclean
## Prepare the ffi library and build for arm
## in LIBFFI_ARM_PATH
LIBFFI_ARM_PATH=/home/conch/conch_service
PKG_CONFIG_PATH=LIBFFI_ARM_PATH/lib/pkgconfig/
## Config to compile
CC=${CROSS_COMPILER_PREFIX}gcc CXX=${CROSS_COMPILER_PREFIX}g++ AR=${CROSS_COMPILER_PREFIX}ar \
    RANLIB=${CROSS_COMPILER_PREFIX}ranlib LDFLAGS=-L/home/conch/conch_service/lib \
    CFLAGS=-I/home/conch/conch_service/include PKG_CONFIG_PATH=/home/conch/conch_service/lib/pkgconfig \
    ./configure --host=$CROSS_COMPILER_HOST --target=$CROSS_COMPILER_HOST \
    --build=x86_64-linux-gnu --prefix=/opt/python_bbb \
    --disable-ipv6 ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no \
    ac_cv_have_long_long_format=yes --enable-shared
# do make
make HOSTPYTHON=/usr/local/bin/python3.8 HOSTPGEN=/usr/local/bin/Parser/pgen \
    BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS-COMPILE=$CROSS_COMPILER_PREFIX \
    CROSS_COMPILE_TARGET=yes HOSTARCH=arm-linux BUILDARCH=arm-linux-gnueabihf
## install in /opt/python_bbb folder
make install HOSTPYTHON=/usr/local/bin/python3.8 \
    BLDSHARED="arm-linux-gnueabihf-gcc -shared" CROSS-COMPILE=$CROSS_COMPILER_PREFIX \
    CROSS_COMPILE_TARGET=yes HOSTARCH=arm-linux BUILDARCH=arm-linux-gnueabihf prefix=/opt/python_bbb

```
### 佈署(deployment)
把intall folder(如果名稱為python3.8.2)的python打包
**tar zcf python3.8.2.tgz python3.8.2**
接著把壓縮檔拷到目標裝置並且解壓縮
**tar zxf python3.8.2.tgz**
接著去/etc/profile.d/目錄下的sh檔新增以下內容
**export PYTHONHOME=YOUR_PYTHON_PATH/python3.8.2**
並且在PATH加上
**YOUR_PYTHON_PATH/python3.8.2/bin**
並且把python3.8.2/lib下的東西拷到usr/lib下面

### 勘誤
如果在make install時發生像是以下的錯誤:
'lsb_release -a' returned non-zero exit status 1.
這時候就把lsb_release的binary改名稱就好了
**sudo mv /usr/bin/lsb_release /usr/bin/lsb_release_back**
### 補充
如果要讓佈署到裝置上的binary用客制化的library path，可以在compile時在makefile設定
LDFLAGS=-R/YOUR_DEVICE_CUSTOM_LIB_PATH

## QT4.8.7 Build for AM335x(Beaglebone Black)
### 環境準備
開發環境在Ubuntu 18.04.4 LTS

- QT的網站下載source code版本4.8.7
 [QT Source code 4.8.7](http://download.qt.io/archive/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.tar.gz)
- QT Creator版本4.3.1(開發QT App的IDE)
 [QT Creator 4.3.1 ](http://download.qt.io/archive/qtcreator/4.3/4.3.1/qt-creator-opensource-linux-x86_64-4.3.1.run)

- 下載TI的Graphics SDK
[下載網頁](http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/gfxsdk/latest/index_FDS.html): 在網頁下載**Graphics_SDK_setuplinux_hardfp_5_01_01_02.bin**
執行並安裝到自己Host的home folder，以下為我自己的安裝路徑
"/home/conch/Graphics_SDK"
- Build TS lib: script如下
````script=
git clone git@github.com:libts/tslib.git
cd  tslib
./autogen.sh
./configure --host=arm-linux-gnueabihf --prefix=/usr/local/tslib --enable-debug=no CC=arm-linux-gnueabihf-gcc
make
make install
````

### 編寫mkspec
解開source code後，可以看到一個mkspec的資料匣
進入mkspecs/qws
創建一個linux-am335x-gnueabihf-g\++資料匣
可以去拷貝linux-arm-gnueabi-g++的資料匣內容
並修改其中的**qmake.conf**檔案如下

````conf=
#
# mkspecs/qws/linux-am335x-gnueabihf-g++/qmake.conf
# qmake configuration for building with arm-linux-gnueabihf-g++
#

include(../../common/linux.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
include(../../common/qws.conf)

load(device_config)
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=gnu++98
QMAKE_CFLAGS_RELEASE    += -O2 -march=armv7-a
QMAKE_CXXFLAGS_RELEASE  += -O2 -march=armv7-a

QMAKE_INCDIR            += /usr/local/tslib/include
QMAKE_LIBDIR            += /usr/local/tslib/lib

# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabihf-gcc -lts
QMAKE_CXX               = arm-linux-gnueabihf-g++ -lts
QMAKE_LINK              = arm-linux-gnueabihf-g++ -lts
QMAKE_LINK_SHLIB        = arm-linux-gnueabihf-g++ -lts

# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabihf-objcopy
QMAKE_STRIP             = arm-linux-gnueabihf-strip

SGX_SDK_ROOT            = /home/conch/Graphics_SDK

QMAKE_INCDIR_OPENGL_ES2 = $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/Include/
QMAKE_INCDIR_OPENGL_ES2 += $$SGX_SDK_ROOT/include
QMAKE_INCDIR_OPENGL_ES2 += $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/
QMAKE_LIBDIR_OPENGL_ES2 = $$SGX_SDK_ROOT/gfx_rel_es8.x/
QMAKE_LIBS_OPENGL_ES2   = -lEGL -lGLESv2 -lGLES_CM -lIMGegl -lsrv_um -lusc

QMAKE_INCDIR_OPENGL     += $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/
QMAKE_LIBDIR_OPENGL     = $$SGX_SDK_ROOT/gfx_rel_es8.x
QMAKE_LIBDIR_OPENGL_QT  = $$SGX_SDK_ROOT/gfx_rel_es8.x
QMAKE_LIBS_OPENGL_ES1   = -lEGL -lGLES_CM -lIMGegl -lsrv_um -lusc

QMAKE_INCDIR_OPENVG     = $$SGX_SDK_ROOT/GFX_Linux_SDK/OVG/SDKPackage/Builds/OVG/Include/
QMAKE_LIBDIR_OPENVG     = $$SGX_SDK_ROOT/gfx_rel_es8.x/
QMAKE_LIBS_OPENVG       = -lEGL -lGLESv2 -lGLES_CM -lIMGegl -lsrv_um -lOpenVG -lOpenVGU

QMAKE_INCDIR            += $$QMAKE_INCDIR_OPENGL_ES2
QMAKE_LIBDIR            += $$QMAKE_LIBDIR_OPENGL_ES2
QMAKE_LIBS              = $$QMAKE_LIBS_OPENGL_ES2 -lrt -lpthread

load(qt_config)
````
### 準備build
- 準備好configure script
在Source folder創建一個shell script(build-config<span>.sh)內容是
````script=
#!/bin/bash
# build-config.sh

echo yes | ./configure \
-prefix /usr/local/Qt4.8.7 \
-release \
-shared \
-opensource \
-fast \
-no-largefile \
-qt-sql-sqlite \
-no-qt3support \
-webkit \
-no-javascript-jit \
-make libs \
-make docs \
-nomake examples \
-nomake docs \
-nomake demo \
-embedded arm \
-xplatform qws/linux-am335x-gnueabihf-g++ \
-no-openssl \
-qt-freetype \
-depths 16,24,32 \
-armfpa \
-little-endian \
-qt-gfx-linuxfb \
-qt-gfx-transformed \
-qt-gfx-multiscreen \
-qt-gfx-vnc \
-qt-kbd-tty \
-qt-mouse-tslib \
-qt-mouse-linuxinput \
-plugin-mouse-linuxtp \
-plugin-mouse-pc \
-no-glib \
-DQT_QLOCALE_USES_FCVT | tee configure.txt
````
然後創建另外一個script(build-arm-qt<span>.sh)並且執行它
````script=
#!/bin/bash
# build-arm-qt.sh
make confclean
if [ -f ./build-config.sh ] ; then
	echo "Start Cofig and build"
	./build-config.sh
	make
	make install
else
	echo "config script not exist"
fi

````
Build的時候請以sudo或是root身分來make install
### Build QT Serial Port
- 環境準備: QT4.8.7先要build好
- Buidl Scipt:
```script=
git clone git://code.qt.io/qt/qtserialport.git
cd qtserialport
git checkout qt4-dev
mkdir build	&& cd build
/usr/local/Qt4.8.7/bin/qmake ../qtserialport.pro
make && sudo make install
```
## Buildroot
### Buildroot init system when make menuconfig
選擇systemd開機
### Make會遇到的錯誤
Network Manager:
configure: error: "--enable-introspection aims to build the settings documentation. This requires GObject introspection for python (pygobject)
修改
package/network-manager/network-manager.mk
> NETWORK_MANAGER_CONF_OPTS = \
> \+ --disable-introspection \
> 	 --disable-tests \
> 	 --disable-qt \
> 	 --disable-more-warnings \

### Buildroot file system必備工具
- dosfstools
- e2fsprogs
### Buildroot之後的root file system
- 需要拷貝/lib/firmware, /lib/modules
- 需要拷貝/lib/libtinfo.so* (給systemctl使用)
- 需要修改/etc/profile中的PS1為 PS1='\u@\h \W# '
- 需要指定init路徑：ln -s /lib/systemd/systemd init
###### tags: `Useful tips` `Embedded Linux` `beaglebone black` `u-boot` `initrd.img` `linux kernel`