文章目录
1 制作根文件系统
在制作文件系统的时候,我们需要使用“BusyBox 工具”,BusyBox最初是由Bruce Perens在199 6年为Debian GNU/Linux安装盘编写的。其目的是在软盘上创建一个可引导的GNU/Linux系统,做安装和救急盘。BusyBox是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox包含了一些简单的工具,例如ls、cat和echo命令等等,还包含了一些更大、更复杂的工具,例grep、find、mount 以及telnet命令。有些人将BusyBox称为Linux工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了Linux的许多工具和命令,也包含了Android系统自带的 shell。
我们可以在其官网下载到,官网地址为:https://busybox.net/。
然后点击官网左侧“Get BusyBox”栏中的“Download Source”进入下载页面。如图 1.2所示:
这是一个开源的程序,并且一直在更新中,我们使用的版本是“busybox-1.29.0.tar.bz2”。
源码在这个视频目录下面。
下面我们来讲解一下如何使用 BusyBox 制作最小文件系统:
1.1 准备源码
首先登录虚拟机ubuntu系统,运行Terminal,切换为root用户,在“/home/topeet”下使用命令“mkdir minilinux”新建目录minilinux。如图 1.1.1所示
然后将“busybox-1.29.0.tar.bz2”通过ssh工具拷贝到我们新建的minilinux目录,使用命令“cd minilinux/”,如图 1.1.2所示:
接着使用命令“tar -vxjf busybox-1.29.0.tar.bz2”,解压busybox,如图 1.1.3所示、
最后使用命令“cd busybox-1.29.0”进入busybox源码,如图 1.1.4所示:
1.2 编译环境
编译器:arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
编译环境:Ubuntu16
然后使用命令“apt-get install libncurses5-dev”确认是否安装ncurses库,没有安装的话后面编译会报错。如图 1.2.1所示:
1.3 支持中文
从busybox1.17.0以上之后,对ls命令不做修改是无法显示中文的。就算是内核设置了支持中文的话,在shell下用ls命令也是无法显示中文的,这是因为busybox1.17.0以后版本对中文的支持进行了限制。要想让busybox1.17.0以上支持中文,需做如下修改。
首先使用命令“vim libbb/printable_string.c”,
然后查找函数printable_string,我们可以看到在第31,32行和45行的操作,大于0x7F的字符直接被break掉,或者直接被“?”代替了。所以就算是linux内核设置了支持中文,也是无法显示出来的。所以我们对这三行进行修改,注释掉对大于0x7f字符的相关操作。如图 1.3.2所示:
修改之后保存退出。
然后使用命令“ vim libbb/unicode.c”
打开之后查找函数unicode_conv_to_printable2,我们可以看到1022行和1030行也对大于0x7f的字符有对应操作,同样的我们这两处做修改,如图 1.3.4所示:
修改之后保存退出。
经过以上修改之后,源码就可以支持中文字符了,但还需要配置 busybox来使能 unicode码,这个稍后会去配置。
1.4 配置busybox
Busybox的编译配置和Linux内核编译配置使用的命令是一样的,下面我们开始配置Busybox。
busybox提供了几种配置:defconfig (缺省配置,也是默认配置)、allyesconfig(最大配置)、 allnoconfig(最小配置),一般选择缺省配置即可。
使用命令“make defconfig ”,即可配置busybox为默认配置。
这一步结束后,将生成.config文件。
我们一般使用“make menuconfig”图形化配置命令,配置“Busybox”。如图 1.4.1所示:
(1)首先回车进入“Settings —>”
(2)然后使用方向键下翻,在“Build Options”栏找到“Cross compiler prefix”,它是指定用什么编译器来编译。如图 1.4.3所示:
(3)接着使用回车选中进入,输入使用的交叉编译工具arm-none-linux-gnueabi-,如图 1.4.4所示:
(4)然后回车选择“Ok”,回到“Settings”设置界面,如图 1.4.5:
(5)接着使用方向键下翻,在“— Installation Options ”栏找到“(./_install) Destination path for ‘make install’ (NEW)”。如图 1.4.6所示:
(6)这个界面是设置编译完Busybox,把最终生成的二进制文件安装到哪个目录下面,使用回车进入,将“./_install”修改为“…/system”。如图 1.4.7所示:
(7)然后回车选择“Ok”,回到“Settings”设置界面,如图 1.4.8:
(8)然后方向键下翻,空格选择“vi-style line editing commands(NEW)”选项,如图 1.4.9:
(9)接着使用左右方向按键,选择“Exit”,回到“Busybox Configuration”界面。如下图所示:方向键下翻找到“Linux Module Utilities —>”。如图 1.4.10所示:
(10)接着回车进入,空格取消选择“Simplified modutils”。如图 1.4.11所示:
(11)然后使用左右方向按键,选择“Exit”,回到“Busybox Configuration”界面。方向键上翻找到“Settings —> ”,如图 1.4.12所示:
(12)然后回车进入,方向键下翻找到“Support Unicod”和“Check $LC_ALL, $LC_CTYPE and $LANG environment variables”,选中这两个选项,即使能 busybox 的 unicode 编码以支持中文 。如图 1.4.13所示:
(13)接着使用左右反方向按键,选择“Exit”,回到“Busybox Configuration”界面。如图 1.4.14所示:
(14)然后使用左右反方向按键,选择“Exit”,选择“Yes”保存配置。如图 1.4.15所示:
至此,busybox 的配置就完成了,如有其他需要可以自行选择配置。如果是初学者建议按照我们的办法配置,以防出错。
1.5 编译busybox
接下来我们开始编译“Busybox”,执行“make”命令,开始编译“Busybox”,如图 1.5.1:
如图 1.5.2为编译完成的截图。
编译完成了,接下来我们需要把编译生成的“二进制文件”安装到刚才我们指定的“…/system”目录里面,安装二进制文件到“…/system”目录,如图 1.5.3,输入命令“make install”。
图 1.5.4为"make install"命令执行完成的截图。
现在我们使用“cd …/system”命令,进入“…/system”目录,看看里面安装的文件,如图 1.5.5:
1.6 整理最小文件系统
上一节通过编译busybox生成了bin、sbin和usr这三个目录,以及 linuxrc 这个文件。busybox 的工作就完成了,还需要一些其他的文件完善文件系统。
1.制作的文件系统还需要新建“dev,etc,lib,mnt,proc,sys,tmp,var”文件夹,使用命令“mkdir dev etc lib mnt proc sys tmp var”,如图 1.6.1:
2.然后使用“cd etc”命令进入到刚才创建的“etc”文件夹,如图 1.6.2:
图 1.6.2
3.然后命令建立“eth0-setting”文件,并在“eth0-setting”文件里输入下面的内容:
IP=192.168.1.230
Mask=255.255.255.0
Gateway=192.168.1.1
DNS=192.168.1.1
MAC=08:90:90:90:90:90
如图 1.6.3:
4.然后保存并退出“eth0-setting”文件,使用“chmod 755 eth0-setting”命令修改文件的权限,如图 1.6.4:
5.接着在etc目录下用“mkdir init.d”命令建立“init.d”文件夹,如图 1.6.5:
6.然后使用“cd init.d”命令进入到“init.d”文件夹,如图 1.6.6:
7.然后在“init.d”文件夹下面使用“vi ifconfig-eth0”命令建立“ifconfig-eth0”文件,如图 1.6.7:
8.然后在“ifconfig-eth0”文件中输入下面的内容
#!/bin/sh
echo -n Try to bring eth0 interface up......>/dev/ttymxc0
if [ -f /etc/eth0-setting ] ; then
source /etc/eth0-setting
if grep -q "^/dev/root / nfs " /etc/mtab ; then
echo -n NFS root ... > /dev/ttymxc0
else
ifconfig eth0 down
ifconfig eth0 hw ether $MAC
ifconfig eth0 $IP netmask $Mask up
route add default gw $Gateway
fi
echo nameserver $DNS > /etc/resolv.conf
else
if grep -q "^/dev/root / nfs " /etc/mtab ; then
echo -n NFS root ... > /dev/ttymxc0
else
/sbin/ifconfig eth0 192.168.253.12 netmask 255.255.255.0 up
fi
fi
echo Done > /dev/ttymxc0
如图 1.6.8:
9.然后保存并退出“ifconfig-eth0”文件,使用“chmod 755 ifconfig-eth0”命令修改权限,如图 1.6.9:
10.接下来在“init.d”文件夹下使用“vi rcS”命令建立“rcS”文件,如图 1.6.10:
11.然后在“rcS”文件输入下面的内容(注意每行前面的行号不要复制):
#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
/bin/hostname iTOP-iMX6UL
#/bin/mount -n -t proc none /proc
#/bin/mount -n -t sysfs none /sys
#/bin/mount -n -t usbfs none /proc/bus/usb
#/bin/mount -t ramfs none /dev
[ -e /proc/1 ] || /bin/mount -n -t proc none /proc
[ -e /sys/class ] || /bin/mount -n -t sysfs none /sys
[ -e /dev/tty ] || /bin/mount -t ramfs none /dev
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s
#/bin/hotplug
# mounting file system specified in /etc/fstab
mkdir -p /dev/pts
mkdir -p /dev/shm
/bin/mount -n -t devpts none /dev/pts -o mode=0622
/bin/mount -n -t tmpfs tmpfs /dev/shm
#/bin/mount -n -t ramfs none /tmp
#/bin/mount -n -t ramfs none /var
mkdir -p /var/empty
mkdir -p /var/log
mkdir -p /var/log/boa
mkdir -p /var/lock
mkdir -p /var/run
mkdir -p /var/tmp
#ln -sf /dev/ttyS2 /dev/tty2
#ln -sf /dev/ttyS2 /dev/tty3
#ln -sf /dev/ttyS2 /dev/tty4
syslogd
/etc/rc.d/init.d/netd start
echo " " > /dev/tty1
echo "Starting networking..." > /dev/tty1
#sleep 1
#/etc/rc.d/init.d/httpd start
#echo " " > /dev/tty1
#echo "Starting web server..." > /dev/tty1
#sleep 1
#/etc/rc.d/init.d/leds start
#echo " " > /dev/tty1
#echo "Starting leds service..." > /dev/tty1
#echo " "
#sleep 1
#echo "*************************************" > /dev/ttySAC2
#echo " http://www.topeet.com.cn " > /dev/ttySAC2
#echo "*************************************" > /dev/ttySAC2
#echo "*************************************"
#echo " http://www.topeet.com.cn "
#echo "*************************************"
mkdir /mnt/disk
sleep 1
/sbin/ifconfig lo 127.0.0.1
/etc/init.d/ifconfig-eth0
如图 1.6.11:
12.然后保存并退出“rcS”文件,使用“chmod 755 rcS”命令修改“rcS”文件的权限,如图 1.6.12:
13.接下来使用“cd …”命令返回到“init.d”文件夹的上一级目录“etc”,如图 1.6.13:
14.接下来在“etc”目录下使用“vi passwd”命令建立文件“passwd”,如图 1.6.14:
15.然后在新建立的“passwd”文件中输入下面的内容
root::0:0:root:/:/bin/sh
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
nobody:*:99:99:Nobody:/:
如图 1.6.15:
16.添加之后保存并退出“passwd”文件,使用“chmod 755 passwd”命令修改“passwd”文件的权限,如图 1.6.16:
17.然后使用“vi profile”命令在“etc”目录建立“profile”文件,如图 1.6.17:
18.然后在“profile”文件中输入下面的内容(注意每行前面的行号不要复制)。
# Ash profile
# vim: syntax=sh
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1
USER="`id -un`"
LOGNAME=$USER
PS1='[$USER@$HOSTNAME]# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
export USER LOGNAME PS1 PATH
如图 1.6.18:
19.然后保存并退出“profile”文件,使用“chmod 755 profile”命令修改“profile”文件的权限,如图 1.6.19:
20.接下来使用“mkdir rc.d”命令在“etc”目录建立文件夹“rc.d”,如图 1.6.20:
21.使用“cd rc.d”命令进入到刚才建立的“rc.d”文件夹,如图 1.6.21:
22.接下来在“rc.d”目录下使用“mkdir init.d”命令建立“init.d”文件夹,如图 1.6.22:
23.然后使用“cd init.d”命令进入到刚才建立的“init.d”文件夹,如图 1.6.23:
24.接着在“init.d”文件夹,使用“vi netd”命令建立“netd”文件,如图 1.6.24:
25.然后在“netd”文件里面输入下面的内容(注意每行前面的行号不要复制):
#!/bin/sh
base=inetd
# See how we were called.
case "$1" in
start)
/usr/sbin/$base
;;
stop)
pid=`/bin/pidof $base`
if [ -n "$pid" ]; then
kill -9 $pid
fi
;;
esac
exit 0
如图 1.6.25:
26.然后保存并退出“netd”文件,使用“chmod 755 netd”命令修改“netd”文件的权限,如图 1.6.26:
27.接着使用“cd …/…/…/”命令返回到“system”目录,如图 1.6.27:
28.接着使用“cd lib”命令进入到“lib”目录,如图 1.6.28:
29.Busybox 编译生成的二进制文件是以动态链接库的形式运行,所以我们需要拷贝编译器里面的库文件到“lib”目录
30.然后可以使用“ls”命令查看一下拷贝过来的库文件
31.库文件拷贝完成后,使用“cd …”命令返回到“system”目录,如图 1.6.29:
32.接下来使用“cd var”命令进入到“var”目录,如图 1.6.30:
33.然后使用“mkdir lib lock log run tmp”命令在“var”目录下建立“lib,lock,log,run,tmp”五个目录,可使用命令“ls”查看,如图 1.6.31:
34.至此,文件系统所需要的文件都已经创建好了,使用“cd …/…/”命令返回到“system”文件夹的上一级目录,如图 1.6.32:
1.6.1 制作文件系统镜像及测试
如图 1.6.1.1所示,是 busybox 制作的根文件系统。
然后使用压缩命令将文件系统打包,生成 rootfs.tar.bz2 文件tar -cjf rootfs.tar.bz2 bin dev etc lib linuxrc mnt proc sbin sys tmp usr var
如图 1.6.1.2所示:
可以看到“rootfs.tar.bz2”压缩包,这个就是制作好的最小 linux 系统镜像。
2 交叉编译Qt源码
一.源码下载
QT官网下载:
http://download.qt.io/new_archive/qt/5.7/5.7.1/
二.编译环境
开发环境:Ubuntu16
编译器:arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
三.编译触摸
触摸源码在这个视频目录下,我们解压触摸源码tslib-1.4.tar.gz,进入解压后的目录。
安装依赖库:
apt-get install autoconf automake libtool pkg-config m4
然后执行./autogen.sh,成功后如图 2.1:
执行 ./configure CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ --host=arm-none-linux-gnueabi --prefix=/opt/tslib1.4 ac_cv_func_malloc_0_nonnull=yes
成功后如图 2.3:
执行make,成功后如图 2.4:
执行make install,成功后如图 2.5:
成功后/opt/tslib1.4/下面会生成以下几个文件:
然后修改配置文件vi /opt/tslib1.4/etc/ts.conf 修改第二行如图 2.7所示:
四.编译QT源码
使用“tar -vxf qt-everywhere-opensource-src-5.7.0”命令解压 Qt5.7 源码,并进入解压生成的“qt-everywhere-opensource-src-5.7.0”目录。
在qt-everywhere-opensource-src-5.7.0目录下,打开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
QT_QPA_DEFAULT_PLATFORM = linux #eglfs
QMAKE_CFLAGS_RELEASE += -O2 -march=armv7-a
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv7-a
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# 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)
然后我们需要用configure生成下Makefile,因为命令比较长,我们一把都是创建一个脚本,然后执行我们这个脚本生成Makefile。
使用“vi autoconfigure.sh”命令,新建“autoconfigure.sh”脚本。脚本内容如下所示。
#!/bin/sh
./configure \
-v \
-prefix /opt/qt5.7.0 \
-release \
-opensource \
-make libs \
-xplatform linux-arm-gnueabi-g++ \
-optimized-qmake \
-pch \
-qt-sql-sqlite \
-qt-libjpeg \
-qt-zlib \
-no-opengl \
-skip qt3d \
-skip qtcanvas3d \
-skip qtpurchasing \
-no-sse2 \
-no-openssl \
-no-nis \
-no-cups \
-no-glib \
-no-iconv \
-nomake examples \
-nomake tools \
-skip qtvirtualkeyboard \
-I/opt/tslib1.4/include \
-L/opt/tslib1.4/lib
exit
脚本创建成功后执行 ./autoconfigure.sh,成功后如图 2.8:
接着使用编译命令“make”,成功后如图 2.9所示。
之后使用安装命令“make install”。完成后,可以在“/opt”目录下可以查看到生成的“qt5.7.0”文件。
3 搭建Qt文件系统
一.开始部署
1.我们在Ubuntu新创建一个文件夹,然后把我们用busybox做好的文件系统拷贝到这个文件下。如图 3.1所示:
2.然后我们解压这个根文件系统到当前所在的路径下。
3.我们在这个解压出来的根文件系统下新创建一个opt的文件夹,如图 3.3所示:
4.我们把上节课编译好的触摸和QT拷贝到我们在这个路径下新创建的opt目录下,如图 3.4所示:
5.我们返回到解压根文件系统的目录下
6.然后我们打开根文件系统的etc/profile文件,并添加一下内容:
添加以下内容:
EVENT=$(cat /proc/bus/input/devices | grep -E 'TSC2007|ft5x0x_ts|goodix-ts' -A4 | tail -n1 | awk '{print $NF}')
export TSLIB_ROOT=/opt/tslib1.4
export TSLIB_TSDEVICE=/dev/input/$EVENT
export TSLIB_CONFFILE=/opt/tslib1.4/etc/ts.conf
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=/opt/tslib1.4/lib/ts
export TSLIB_CONSOLEDEVICE=none
export QT_ROOT=/opt/qt5.7.0
export QT_QPA_FONTDIR=$QT_ROOT/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:$QT_ROOT/lib:$TSLIB_ROOT/lib/
解释:
自动获取触摸的设备节点,变量EVENT的值可能是event0,event2…等。EVENT=$(cat /proc/bus/input/devices | grep -E 'TSC2007|ft5x0x_ts|goodix-ts' -A4 | tail -n1 | awk '{print $NF}')
触摸库所在的位置export TSLIB_ROOT=/opt/tslib1.4
触摸屏设备文件export TSLIB_TSDEVICE=/dev/input/$EVENT
tslib模块配置文件export TSLIB_CONFFILE=/opt/tslib1.4/etc/ts.conf
指定触摸屏校准文件pintercal的存放位置export TSLIB_CALIBFILE=/etc/pointercal
设定控制台设备为 none ,否则默认为 /dev/tty ,这样可以避免出现“ open consoledevice: No such file or directory KDSETMODE: Bad file descriptor ” 的错误export TSLIB_CONSOLEDEVICE=none
qt库所在的路径export QT_ROOT=/opt/qt5.7.0
qt字库的目录export QT_QPA_FONTDIR=$QT_ROOT/lib/fonts
qt插件的目录export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
指定帧缓冲设备/dev/fb0export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
添加QT和触摸库的环境变量export LD_LIBRARY_PATH= /lib:/usr/lib:/usr/local/lib:$QT_ROOT/lib:$TSLIB_ROOT/lib/
7.把视频所在目录下的字库文件拷贝到根文件系统的qt库的/lib/fonts下,没有这个路径手动创建一个路径,如图 3.7所示:
8.然后我们回到根文件系统的lib目录下,将视频目录下的libstdc.tar.gz拷贝到lib解压,并输入命令:ln -s libstdc++.so.6.0.19 libstdc++.so.6
如图 3.8所示:
9.然后我们把视频目录下的测试历程拷贝到根文件系统的opt目录下,并改成777权限,如图 3.9所示:
10.然后我们打包这个文件系统,并烧写到开发板上测试。如图 3.10所示:
11.测试触摸
校准:进入 /opt/tslib1.4/bin/目录下 运行五点校准测试程序./ts_calibrate,然后依次点击指示的触摸点:
完成后运行测试例程./ts_test,用手拖动十字标志,能跟随手指移动说明触摸功能正常。
进入/opt/目录,运行测试例程,./fingerpaint
打开后如下图,用手划动屏幕,发现触摸不准,
先在/etc/profile文件下添加环境变量。export QT_QPA_FB_TSLIB=1
重启后删除校准文件:rm /etc/pointercal,
进入/opt/tslib1.4/bin/,进行五点校准,校准完成后进入/opt/目录下执行测试程序./fingerpaint,箭头能和触摸位置一致则校准成功