一、概述:
最近使用友善之臂Tiny6410开发板进行Qt应用程序的开发,由于友善之臂为开发板移植的是Qt4的库,用着略有不爽,而且友善之臂官方提供的文件系统也比较乱。
所以--作者本着处女座对脏乱差的零容忍态度,做了以下3件事:
① 使用Busybox1.26.0重新制作根文件系统,革了友善之臂Tiny6410脏乱差官方旧文件系统的命
② 移植了tslib1.4,以支持Tiny6410的一线触摸屏
③ 对Tiny6410进行了Qt-Embedded-5.6库的移植
做这3件事的过程中,历经各种艰难险阻,其坎坷不亚于当年大唐圣僧西天取经;故写下这篇博客,希望对后继者有所帮助!
二、准备工作:
① 下载busybox-1.26.0.tar.bz2 Busybox源码下载地址
② 下载qt-everywhren-opensource-src-5.6.0.tar.gz QT-5.6.0源码下载地址
③ 下载tslib-1.4.tar.gz tslib-1.4源码下载地址
④ 下载友善之臂提供的一线触摸屏的tslib补丁 Tiny6410-tslib补丁下载地址
⑤ 下载交叉编译器arm-2009q3.tar.bz2 -- ( gcc-v4.4.1版本的交叉链 ) arm交叉工具链下载地址
⑥ 准备好友善之臂移植好的内核源码linux-2.6.38-mini6410.tar.gz -- (在 友善A盘/Linux)
⑦ 准备好友善之臂移植好的bootloader源码u-boot-mini6410.tar.gz -- (在 友善A盘/Linux)
⑧ 准备好友善之臂提供的mktools-20120518.tar.gz -- (在 友善A盘/Linux)
三、移植环境声明:
① 宿主机:ubuntu-14.04,内核版本为-Linux ubuntu 4.13.0-38-generic,系统自带编译器为-gcc v5.4.0
② 交叉编译器:arm-none-linux-gnueabi-gcc v4.4.1
③ 硬件:Tiny6410-mlc-256M、友善之臂S70屏
四、开始:
1. 首先安装交叉编译链arm-none-linux-gnueabi-gcc,这个废话不多说,不会的请自行百度。
2. 重新编译uboot、kernel,生成uboot.bin 和 zImage,请参考友善之臂《Tiny6410 Linux开发指南》。
3. 重新制作根文件系统:
① 编译busybox,不会的请参考 :《如何配置及编译busybox》、《编译busybox报错及解决》
(补充-这篇博客最后少了make install,执行完这条命令后则会在当前目录生成 _install目录)
② 创建根文件目录,比如我的 :
mkdir /home/share/rootfs
③ 拷贝编译busybox生成的_install :
cp /xxxx/busybox-1.26.0/_install/* /home/share/rootfs -rd
④ 在rootfs目录下创建根文件系统标准目录:
mkdir dev lib etc home mnt opt proc root sys var
⑤ 拷贝busybox的示例启动脚本:
cp /xxxx/busybox-1.26.0/example/bootfloppy/etc /home/share/rootfs -rf
⑥ 修改etc/inittab的内容如下 :
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
⑦ 修改etc/fstab的内容如下:
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
⑧ 修改etc/init.d/rcS的内容如下:
#! /bin/sh
#Mount the filesystem pointed by /etc/fstab. By Eaon -- 2018-4-17
/bin/mount -a
#MK Dev_node autoly. By Eaon -- 2018-4-17
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#Init the net. By Eaon -- 2018-4-20
/sbin/ifconfig lo 127.0.0.1
source /etc/init.d/eth0-setting
DEV_ADDR=`cat /sys/class/net/eth0/address`
if [ "$DEV_ADDR" = "00:00:00:00:00:00" ]; then
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
fi
ifconfig eth0 $IP netmask $Mask up
route add default gw $Gateway
#load machine name.
/bin/hostname -F /etc/hostname
⑨ 修改profile的内容如下:
#explain platform name. By Eaon -- 2018-4-20
PS1='[\u@\h \W]\#'
HOSTNAME=`/bin/hostname`
export HOSTNAME PS1
⑩ 在rootfs/etc/下创建hostname文件( vim etc/hostname ),写入你想要显示的主机名,比如我的:
vim etc/hostname
EaonMarch
⑪ 在rootfs/etc/下创建passwd文件( vim etc/passwd ),增加内容如下:
root:x:0:0:root:/root:/bin/sh
⑫ 解压安装最开始准备的mktools-20120518.tar.gz,请参考友善之臂《Tiny6410 Linux开发指南》。
⑬ 在dev目录下创建标准的控制台设备节点和NULL设备节点:
mknod console c 5 1
mknod null c 1 3
⑭ 拷贝交叉编译器的链接库到根文件系统的lib目录下 :
cp /xxxx/arm-2009q3/arm-none-linux-gnueabi/libc/lib/* /xxxx/rootfs/lib -d
⑮ mkubimage-mlc2 ./rootfs ./EaonRootFS.ubi:
自己的根文件系统制作完成!
将uboot、zImage、EaonRootFS.ubi烧进开发板,验证根文件系统是否正确。
下图为我的文件系统挂载之后系统进入控制台的示例。
4. 根文件系统制作完毕,意味着可以在板子上跑应用程序了,开始tslib-1.4的移植:
注: 因为友善Tiny6410是一线触摸屏,不是标准的输入设备,所以需要修改tslib的源码
① 解压友善之臂提供的tslib补丁: tar -vxf one-wire-ts-input-src-20111026.tar.gz
② 解压tslib源码包: tar -vxf tslib-1.4.tar.gz
③ 将补丁包,one-wire-ts-input/one-wire-ts-input.c文件中 \
static int misc_read(struct tslib_module_info *inf, struct ts_sample *samp, int nr)函数的内容,\
替换给tslib源码包,tslib/plugins/input-raw.c文件中的 \
static int ts_input_read(struct tslib_module_info *inf,struct ts_sample *samp, int nr)函数。
static int ts_input_read(struct tslib_module_info *inf,
struct ts_sample *samp, int nr)
{
struct tsdev *ts = inf->dev;
int ret;
unsigned ts_status;
ret = read(ts->fd, &ts_status, sizeof ts_status);
if (ret < 0) {
return 0;
}
if (ret == 0) {
return 0;
}
samp->x = ((ts_status) >> 16) & 0x7FFF;
samp->y = ts_status & 0x7FFF;
samp->pressure = ts_status >> 31;
gettimeofday(&samp->tv,NULL);
nr = nr;
return 1;
}
④ 安装宿主机的支持库,我的宿主机为Ubuntu14.04,其他版本宿主机请自行安装对应链接库:
sudo apt-get install autoconf automake libtool
⑤ 进入tslib目录,执行自动脚本 :
./autogen.sh
⑥ 生成cache文件:
echo "ac_cv_func_malloc_0_nonnull=yes" > tmp.cache
⑦ 配置交叉链及安装路径 :
./configure --host=arm-none-linux-gnueabi --prefix=/opt/tslibInstall --cache-file=tmp.cache
⑧ make && make install
⑨ make install之后可能会出现如下报警提示 :
libtool: warning: remember to run 'libtool --finish /opt/tslibInstall/lib/ts/'
按照提示运行libtool工具 : libtool --finish /opt/tslibInstall/lib/ts/
⑩ 将宿主机下编译好的tslibInstall拷贝到板子的根文件系统中,路径为rootfs/opt :
cp /opt/tslibInstall /xxxx/rootfs/opt -rd
⑪ 修改/xxxx/rootfs/etc/profile ,在末尾增加以下几行,声明tslib的环境变量 :
export TSLIB_ROOT=/opt/tslibInstall
export TSLIB_TSDEVICE=/dev/touchscreen-1wire
export TSLIB_CALIBFILE=$TSLIB_ROOT/etc/pointercal
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONSOLEDEVICE=/dev/tty
export TSLIB_FBDEVICE=/dev/fb0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib
⑫ 修改rootfs/opt/tslibInstall/etc/ts.conf :
将 # module_raw input注释取消,注意module_raw input要定格,不要留空。
⑬ 重新制作根文件系统,烧录后运行tslibInstall/bin/ts_calibrate及tslibInstall/bin/ts_test进行测试:
自此,tslib移植成功!
5. 移植Qt-5.6.0 :
① 解压源码并进入源码所在目录 : tar -vxf qt-everywhere-opensource-src-5.6.0.tar.gz
② 配置编译环境 : vim qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
内容修改如下:
#
# qmake configuration for building with arm-linux-gnueabi-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
QT_QPA_DEFAULT_PLATFORM =linuxfb
QMAKE_CFLAGS_RELEASE += -O2 -march=armv6
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv6
# modifications to g++.conf
QMAKE_CC = arm-none-linux-gnueabi-gcc
QMAKE_CXX = arm-none-linux-gnueabi-g++
QMAKE_LINK = arm-none-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR = arm-none-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-none-linux-gnueabi-objcopy
QMAKE_NM = arm-none-linux-gnueabi-nm -P
QMAKE_STRIP = arm-none-linux-gnueabi-strip
load(qt_config)
#
# end
#
修改说明:
QT_QPA_DEFAULT_PLATFORM选项是制定图形插件,Qt5将各平台底层抽象为一个qpa插件。
通常mac上是cocoa;
window上是windows;
Linux X11上是xcb,如果有OPENGL支持,那么选择eglfs,而对于无硬件加速的设备,则选择linuxfb。
armv6指定cpu的架构,s3c6410的cpu为armv6架构,其他处理器请指明为自己的架构。
arm-none-linux-gnueabi-xxx,指明交叉编译器,若为其他编译器,请指明为自己的。
③ 生成Makefile(qt参数配置请参考 -->):《Qt源码编译configure参数》、《如何正确移植QtE5》
./configure
-release
-opensource
-xplatform linux-arm-gnueabi-g++
-prefix /opt/qtE
-no-c++11
-no-iconv
-no-dbus
-I /opt/tslibInstall/include
-L /opt/tslibInstall/lib
注:-I 及 -L指明了tslib在宿主机中头文件及链接库的路径。
④ make && make install :
编译并安装qtE,时间有点漫长,我的机器需要1小时左右,请耐心等待。
⑤ 编译并安装完成,在/opt/qtE下安装了qtE5.6.0,声明环境变量,方便使用:
vim /etc/profile
在最后加上: export PATH=$PATH:/opt/qtE/bin
生效环境变量: source /etc/profile
由于Ubuntu在/usr/bin下自带qmake,为了区分,将qtE的qmake重命名为qmakeE:
mv /opt/qtE/bin/qmake /opt/qtE/bin/qmakeE
⑥ 测试qtE是否安装成功 : qmakeE -v
⑦ 部署开发板上的Qt库环境:
A. 在/xxxx/rootfs/lib/目录下创建qtE目录: mkdir /xxxx/rootfs/lib/qtE
B. 将/opt/qtE/下的lib及piugins目录拷贝到/xxxx/rootfs/lib/qtE :
cp /opt/qtE/lib /xxxx/rootfs/lib/qtE/ -rd
cp /opt/qtE/plugins /xxxx/rootfs/lib/qtE/ -rd
C. 在/xxxx/rootfs/etc/profile末尾增添以下环境变量声明 :
export QTDIR=/lib/qtE
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export QT_QPA_FONTDIR=$QTDIR/lib/fonts
export QT_QPA_GENERIC_PLUGINS=tslib
export QWS_MOUSE_PROTO=/dev/touchscreen-1wire
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib
⑧ 一切就绪,还等什么呢?在开发板上跑一下Qt触摸屏的测试用例!!
A. cd /opt/qtE/examples/touch
B. qmakeE
C. make
D. 在dials/目录下就会产生可执行文件dials,将它拷贝到/xxxx/rootfs/usr/bin
E. 重新制作根文件系统
F. 烧录根文件系统,然后测试触摸屏例程:
先运行/opt/tslibInstall/bin/ts_calibrate校准触摸屏
然后运行/usr/bin/dials
可以看到:上面那一排表盘的箭头被我任意地拖动了一下,改变了箭头指向的方向。
自此,在Tiny6410上,tslib1.4 + QtE5.6.0移植完成!!
6. 补充说明:
如果想要支持中文字库,可以拷贝windows下的字库文件到板子的/lib/qtE/lib/fonts下。
分享出作者制作好的镜像文件:u-boot.bin、zImage、rootfs.ubi --> 《镜像文件链接地址》
分享出作者构建的根文件系统:rootfs --> 《构建的根文件系统》