大家好,欢迎前来讨论
这篇文章介绍的是qt5.6在jz2440单板上的移植过程
..........................................................2018.3.27重新排版.............................................................................................................................
一、实验环境
(1)编译工具链
arm-Linux-gcc-4.4.3.tar.gz
下载地址:http://www.arm9.net/download.asp
(2)u-boot
u-boot-2012.04.01
u-boot-2012.04.01_100ask.patch
(3)linux_kernel
linux-3.4.2
linux-3.4.2_100ask.patch
(4)虚拟机
韦老大_9.10-Ubuntu
(5)busybox
busybox-1.22.1.tar.bz2
(6)tslib
tslib-1.4.tar.gz
(7)qt5.6 源码
qt-everywhere-opensource-src-5.6.0.tar.gz
(8)S3C2440开发板
JZ2440
二、更换交叉编译器
cd /work/tools/
sudo tar zxvf arm-linux-gcc-4.4.3.tar.gz -C / #展开在根目录_sudo 创建/opt/FriendlyARM/toolschain/4.4.3/bin
ls /opt/FriendlyARM/toolschain/4.4.3/bin #检查是否生成了编译目录
修改环境变量
sudo vi /etc/environment
#PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.2/bin/"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.4.3/bin"
重启使/etc/environment生效
或者执行下面命令
source /etc/environment source命令也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
同时为所有用户增加环境变量
sudo vim /etc/profile
export PATH=$PATH:/opt/FriendlyARM/toolschain/4.4.3/binsource /etc/profile
查看版本
arm-linux-gcc –v
gcc version 4.4.3 (ctng-1.6.1)
sudo su
arm-linux-gcc –v
gcc version 4.4.3 (ctng-1.6.1)
exit
三、编译u-boot
tar xjf u-boot-2012.04.01.tar.bz2
cd u-boot-2012.04.01/
patch -p1 < ../u-boot-2012.04.01.path
vi include/configs/smdk2440.h
因为坏块问题修改uboot中include/configs/smdk2440.h中MTDPARTS_DEFAULT 使内核分区为4M。
make smdk2440_config
make
四、编译内核
cd /work/system/
tar xjf linux-3.4.2.tar.bz2
patch -p1 < ../linux-3.4.2_skk.patch #我的补丁 也可以使用韦老大补丁
cp config_ok .config
修改linux-3.4.2/arch/arm/mach-s3c24xx/common-smdk.c的smdk_default_nand_part函数,内核分区改为4M
make uImage #时间够洗个澡 不要傻等
.
.
.
.
编译完的uImage 在 /arch/arm/boot 目录下
五、制作文件系统
1、解压
tar jxvf busybox-1.22.1.tar.bz2
2、配置
Busybox Settings ->
general configuration ->
[*] don't use /usr //选中它 否则会破坏虚拟机
build options->
cross comliler prefix = arm-linux- //选择交叉编译工具
installtion options->
busybox installation prefix = /work/my_rootfs //指定安装路径
3、编译&安装
mkdir -p /work/my_rootfs //安装路径
make
make install
cd /work/my_rootfs
ls //查看是否安装成功
编译安装完毕之后,我们的文件系统就生成在 /work/my_roofs 目录下了
4、创建 /etc/inittab
mkdir -p /work/my_rootfs/etc
vi /work/my_rootfs/etc/inittab
# /etc/inittab
# 启动脚本/etc/init.d/rcS
::sysinit:/etc/init.d/rcS
# 启动 shell
::askfirst:-/bin/sh
# 重启关机前 卸载文件系统
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
5、创建 /etc/init.d/rcS
mkdir -p /work/my_rootfs/etc/init.d
vi /work/my_rootfs/etc/init.d/rcS
# 这是一个脚本文件,用/bin/sh解析
#!/bin/sh
ifconfig eth0 192.168.1.7
# 挂载文件系统
mount -a
# 使用内存文件系统
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# 设置IP
#/sbin/ifconfig eth0 192.168.1.17 #nfs不需要
# 挂载 /etc/fstab 中的文件系统
mount -a
exec /etc/rc.local
6、创建rc.local
vi /work/my_rootfs/etc/rc.local
#!/bin/sh
. /etc/profile //注意.后边有个空格!
7、创建/etc/fstab
vi /work/my_rootfs/etc/fstab
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
8、构建 /dev 目录
mkdir -p /work/my_rootfs/dev
cd /work/my_rootfs/dev
sudo mknod console c 5 1
sudo mknod null c 1 3
9、创建其它目录
mkdir proc mnt tmp sys root usr lib
10、拷贝Lib
cd /opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib
cp *.so* /work/my_rootfs/lib -d
cd /opt/FriendlyARM/toolschain/4.4.3/lib
cp *.so* /work/my_rootfs/lib -d
六、移植 tslib
1、解压&配置&编译
编译:
tar xzf tslib-1.4.tar.gz
cd tslib
./autogen.sh
mkdir tmp
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache
./configure --host=arm-linux --cache-file=arm-linux.cache --prefix=$(pwd)/tmp
make
安装:
make install
3将制作好的 tslib 移动到我们制作的文件系统
cd tmp
cp * -rf /work/nfs_root/my_rootfs
2、更改 tslib 配置文件
(1)cd /work/my_rootfs/etc/
(2)sudo vi ts.conf
去掉# module_raw input 前面的 “#” 和空格
4、添加 tslib 环境变量
vi /work/my_rootfs/etc/profile
#!/bin/sh
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
此时,tslib 就已经移植好了,你可以挂载 nfs 文件系统启动,cd /usr/local/tslib/bin
/*******************************************************************************
测试之前要挂载触摸屏驱动
有selected device is not a touchscreen I understand错误时候
cd /opt/FriendlyARM/toolschain/4.4.3/ #你/etc/environment中的路径
sudo vi arm-none-linux-gnueabi/sys-root/usr/include/linux/input.h +32
#defineEV_VERSION 0x010000
改为
#defineEV_VERSION 0x010001
在tslib中
make clean
重新编译
/*********************************************************************************
七、挂载nfs根文件系统
(1)将得到的u-boot.bin uImage my_rootfs.yaffs2 烧写进单板
cd /work
mkyaffs2image my_rootfs my_rootfs.yaffs2
tftp 30000000 uImage; nand erase.part kernel; nand write 30000000 kernel
tftp 30000000 my_rootfs.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 460000 $filesize #460000是计算4M kernel后的值
0x000000000000-0x000000040000 : "bootloader"
0x000000040000-0x000000060000 : "params"
0x000000060000-0x000000460000 : "kernel"
0x000000460000-0x000010000000 : "rootfs"
/ # ls
bin etc linuxrc mnt root sys usr
dev lib lost+found proc sbin tmp
/ #
说明u-boot kernel my_rootfs没问题,接下来挂载nfs文件系统
(2)接下来挂载nfs文件系统
手动挂载:
mount -t nfs -o nolock,vers=2 192.168.1.2:/work/nfs_root/my_rootfs /mnt
nfs启动:
服务器配置:
cp -r /work/my_rootfs /work/nfs_root/
sudo vi /etc/exports
/work/nfs_root/my_rootfs *(rw,sync,no_root_squash)
sudo /etc/init.d/nfs-kernel-server restart
showmount -e
u-boot配置:
set bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 rootfstype=yaffs2
set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.2:/work/nfs_root/my_rootfs ip=192.168.1.7:192.168.1.2:192.168.1.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200 rootfstype=yaffs2
save
reset
/********************************手贱改了etc文件夹权限 ,系统不能用了 。。。。。。。。。。。。。。。。。。。。。。。。。。。
花了不少时间重新搭建环境 奉劝朋友们文件一定要做好备份
*****************************************************************************************************************************/
八.移植qt5.6
1、解压
tar zxvf qt-everywhere-opensource-src-5.6.0.tar
2、修改编译配置
cd /work/qt-everywhere-opensource-src-5.6.0/qtbase/mkspecs/linux-arm-gnueabi-g++
vi qmake.conf
针对于 2440 增加:
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t
march 指的 cpu 架构,针对 2440 来说是 armv4t
mtune 指的 cpu 名字,针对 2440 来说是 arm920t
如果你是 A8 的板子 ,可以参考下边的配置
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a8
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a8
如果你是 A9 的板子 ,可以参考下边的配置
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a9
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv7-a -mtune=cortex-a9
将以下部分
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabi-gcc
QMAKE_CXX = arm-linux-gnueabi-g++
QMAKE_LINK = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabi-objcopy
QMAKE_NM = arm-linux-gnueabi-nm -P
QMAKE_STRIP = arm-linux-gnueabi-strip
修改为:-lts 是指在链接时链接 tslib 库
# modifications to g++.conf
QMAKE_CC = arm-none-linux-gnueabi-gcc -lts
QMAKE_CXX = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++ -lts
# 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
注意:全部复制
makeinstall 如果arm-none-linux-gnueabi-strip报错
将 QMAKE_STRIP = arm-none-linux-gnueabi-strip 改为绝对路径
如QMAKE_STRIP = /opt/FriendlyARM/toolschain/4.4.3/bin/arm-none-linux-gnueabi-strip
3、配置编译
sudo mkdir -p /usr/local/Qt5.6
cd ../../../
./configure -prefix /usr/local/Qt5.6 \
-opensource \
-release \
-confirm-license \
-xplatform linux-arm-gnueabi-g++ \
-shared \
-qt-zlib \
-no-gif \
-qt-libjpeg \
-no-nis \
-no-opengl \
-no-cups \
-no-glib \
-no-dbus \
-no-rpath \
-no-sse2 -no-sse3 -no-ssse3 -no-sse4.1 -no-sse4.2 \
-no-avx \
-no-openssl \
-nomake tools \
-qreal float \
-qt-libpng \
-tslib \
-nomake examples \
-I /usr/local/tslib/include \
-L /usr/local/tslib/lib
make -j4
sudo make install
如果使用的不是韦老大的虚拟机编译过程中可能报关于libxcb的错误,查看 qtbase/src/plugins/platforms/xcb 底下的 readme 安装相应的库就可以了。
4、将移植好的 qt 打包到开发板
cd /usr/local
sudo tar zcvf Qt5.6.tar.gz Qt5.6
cp Qt5.6.tar.gz /work/my_rootfs/usr/local/
tar zxvf Qt5.6.tar.gz
rm Qt5.6.tar.gz
rm -r doc include bin mkspecs qml translations
5、设置qt相关的环境变量
此部分可以参考qt官方问文档:http://doc.qt.io/qt-5/embedded-linux.html ,这我这仅仅是设置支持了触摸屏,你可以参考官方设置支持键盘,鼠标等等。
在文件系统 /etc/profile 里添加
export QTEDIR=/usr/local/Qt5.6
export LD_LIBRARY_PATH=/usr/local/Qt5.6/lib:$LD_LIBRARY_PATH
export QT_QPA_GENERIC_PLUGINS=tslib
export QT_QPA_FONTDIR=$QTEDIR/lib/fonts
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTEDIR/plugins
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=480x272:mmSize=480x272:offset=0x0:tty=/dev/tty1
export QT_QPA_FB_TSLIB=1
mmSize=480x272部分请根据自己的开发板进行修改,JZ2440 V3 4.3寸LCD 用上面的参数即可。
此时,qt 已经移植完毕,你可以打包放入你的 nfs 目录启动进行测试了,至于制作 yaffs2 jffs2 等文件系统请参考:http://blog.csdn.net/lizuobin2/article/details/52589215 ,qt库比较大,烧录的时候可能比较困难,可以先将QT去除,打包成文件系统大约之后20M不到,烧录到开发板之后,启动内核,通过nfs tftp等工具,再将打包好的Qt传到板子上展开即可。
九、测试Qt应用程序
win下安装qt5.6建立一个简单测试程序
将windows下编辑好的源码拷贝到虚拟机上,切换到源码目录
/usr/local/Qt5.6/bin/qmake
make
即可生成可执行文件,拿到开发板测试即可。
嫌费事的话,将 qmake 添加到环境变量里
sudo vi /etc/profile
添加
export PATH=$PATH:/opt/FriendlyARM/toolschain/4.4.3/bin
export QTDIR=/usr/local/
export PATH=$QTDIR/Qt5.6/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/Qt5.6/lib:$LD_LIBRARY_PATH
source /etc/profile
qmake -v查看
Using Qt version 5.6.0 in /usr/local/Qt5.6/lib
在测试过程中我发现程序跑起来没问题,但是有以下两条错误信息:
QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed
QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open failed
解决:
下载libiconv-1.14.tar.gz
网址:https://ftp.gnu.org/pub/gnu/libiconv/
tar zxvf libiconv-1.14.tar.gz
mkdir -p /usr/local/libiconv
./configure --host=arm-none-linux-gnueabi --prefix=/usr/local/libiconv CC=arm-none-linux-gnueabi-gcc LDFLAGS="-L/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/sys-root/lib" --enable-static
make
sudo -i
make install
把安装目录/lib 下的 preloadable_libiconv.so 文件系统的 /lib 下, 在 /etc/profile 中添加
export LD_PRELOAD=/lib/preloadable_libiconv.so
使Qt支持中文
在测试过程中很悲剧的发现移植好的qt不支持中文,强大度娘给了我答案。
下载字库 链接
https://www.fontke.com/download/?hash=F64%2BEmIMSWHJA%2BYv3FGWkMdrPBtQL1xzx4HoCOOrZKL%2FpvijYSUnFra%2FdCr8u8DKbFbrCmZ4BvgzBiyEKUetzeexKEj%2BeQWPyq%2FiJJZ83Pw%3D&name=DroidSansFallback.ttf
将DroidSansFallback.ttf 放到文件系统 /usr/local/Qt5.6/lib/fonts 目录下,虽然Qt自带了很多字库了,但是都没有中文的。
然后在使用qt creator 开发qt应用程序时,在项目中添加
QT += gui
mainwondows.cpp加上
包含头文件 #include <QFontDatabase>
代码中设置使用的字体。
int id = QFontDatabase::addApplicationFont("/usr/local/Qt5.6/lib/fonts/DroidSansFallback.ttf");
QString msyh = QFontDatabase::applicationFontFamilies (id).at(0);
QFont font(msyh,10);
font.setPointSize(20);
this->setFont(font);
至此qt移植已经完成
总结一下移植过程步骤繁琐,但是仅仅是过程的累积
尽管碰到许多困难。也要一个一个解决,相信付出总会有回报
已经写了不少了,qt移植的基本工作已经完成,接下来是一些修饰工作
因为我所用的jz2440SDRAM是63M,然而包含qt库打包的yaffs2文件系统有78M
不能直接下载
所以博主将qt文件夹打包成压缩包 剩余制作成yaffs2,
烧写完成yaffs2后通过tftp或者ftp把qt下载到开发板
因此需要配置文件系统到,使其支持telnet , ftp 和tftp
十、配置文件系统,使其支持telnet , ftp 和tftp
我们的busybox1.22.0已经支持的telnet , ftp 和tftp
只要进行相应参数设置就可以启动
1.如果一个用户没有密码,那它在linux系统中就是不存在的用户,无法用这个用户登录。现在已经使用NFS启动成功,那么顺便设置一下root用户的密码(本操作在开发板上完成)。
在etc目录下增加passwd、group
$ cd /work/busybox-1.21.0/rootfs/etc
$ touch passwd
$ touch group
$ sudo chmod 777 passwd
$ sudo chmod 777 group
$ vi passwd ,内容为:
root:x:0:0:root:/root:/bin/sh
$ vi group,内容为:
root:x:0:
启动开发板执行
$ passwd root
设置密码
2. 添加telnet功能
busybox默认已经支持telnetd和telnet,开发板只要启动telnet服务
#telnetd
securecrt快速连接选择Telnet协议,主机名:root
3.添加ftp功能
制作文件系统时新建/etc/inetd.conf
cd /work/busybox-1.21.0/rootfs/etc
$touch inetd.conf
$chmod 777 inetd.conf
$vi inetd.conf,内容如下
21 stream tcpnowait root ftpd ftpd -w /
开发板开启ftpd
$inetd
就可以用filezilla输入主机用户名密码端口(默认21),开发板window之间互传文件了
如果提示连接失败,尝试输入
tcpsvd 0 21 ftpd -w /root & #文件会下载到根目录root文件夹下
4.添加tftp功能
跟ftp类似,也是把配置信息写入脚本。
$vi inetd.conf,追加一行:
69 dgram udpnowait root /usr/sbin/tftpd tftpd -l
测试tftp
window打开tftpd32,选择tftp Client,输入Host ,Port和Local File(要下载的文件必须在Current Directory设置的目录下)
开发板执行tftp -g -r 1.docx 192.168.1.100 把window LocalFile下的1.docx文件
至此,文件系统已经支持telnet ftp tftp,再用NFS启动一下,确保没问题后烧到开发板//当然也可以不烧到开发板,一直用NFS。
最后的工作
制作yaffs2根文件系统:
cd /work/nfs_root/
sudo cp -r my_rootfs my_rootfs_ya2
cd /work/nfs_root/my_rootfs_ya2/usr/local/
sudo tar cjf Qt5.6.tar.bz2 Qt5.6
cp Qt5.6.tar.bz2 /work/qt #临时存放
sudo rm -rf Qt5.6
sudo rm Qt5.6.tar.bz2
cd ../../..
sudo mkyaffs2image my_rootfs_ya2 my_rootfs_ready_qt5.6.yaffs2
sudo chmod 777 my_rootfs_ready_qt5.6.yaffs2
这样制作的yaffs2只要18.4M完全可以下载
u-boot:
set bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 rootfstype=yaffs2
tftp 30000000 my_rootfs_ready_qt5.6.yaffs2; nand erase.part rootfs; nand write.yaffs 30000000 460000 $filesize
执行
tcpsvd 0 21 ftpd -w /root &
把Qt5.6.tar.bz2传输进单板
cd root
cp Qt5.6.tar.bz2 /usr/local/
rm Qt5.6.tar.bz2
cd /usr/local/
tar xjf Qt5.6.tar.bz2
rm Qt5.6.tar.bz2
运行测试程序,正常!!!
完结。
错误备注:
sudo make install。由于安装到系统目录/usr/local,所以加了sudo执行。就这步,出现了问题:
../libtool:line XXXX:arm-linux-ranlib command not found
在终端检查,发现arm-linux-ranlib可以在系统的PATH中找到,因为我已经把/optl/arm/4.3.2/bin添加到了PATH中。
那为什么还提示说找不到arm-linux-ranlib呢?
原因如下:
1.我添加arm交叉编译器目录到PATH中是放在//etc/profile里的,这是用户的配置文件,我的用户为yan。
2.执行make install时,加了sudo前缀,变成了root的工作环境和root的权限。
根据以上两点,make install是在root下做的,而arm-linux-ranlib在wmm用户的工作环境中才能找到。所以产生了这里的错误。
那我既要取得root权限,又要具有当前用户yan的工作环境,怎办呢?
解决如下:
执行make install之前,先用下sudo -i命令取得root权限。然后再执行make install。
su 和 sudo 的区别:
1.共同点:都是root用户的权限;
2.不同点:su仅仅取得root权限,工作环境不变,还是在切换之前用户的工作环境;sudo是完全取得root的权限和root的工作环境。
注意:sudo su切换到root时原用户的环境变量也一并丢失。应使用sudo -i
索性就手动添加PATH环境变量export $PATH=/opt/arm/4.3.2./bin:$PATH
然后make install,安装成功
参考:
http://blog.csdn.net/fengyuwuzu0519/article/details/73129643
http://blog.csdn.net/lizuobin2/article/details/52673494
http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d678b975f2482c25f93130a1c187b9de07b655a19d3c77f6416af3f5ee0ed307134082aa09bbfd20c82afd7756fde28673043914062c419d9dc47559f7bcc1da3b81897adf04484afa2938c0844cb235b21d0e78a2a1715b978f06560bef9c61b490907ba9c6c38b94e7758cb7e07ea11&p=976ac64ad48b11a058ed923e56438b&newp=8e769a4786cc41af5eb3cf3454508b231610db2151d2da1f&user=baidu&fm=sc&query=arm-linux-ranlib:+command+not+found&qid=&p1=1