----------------------------------------------------------------------------------------------------------------------------

内核版本:linux 5.2.8

根文件系统:busybox 1.25.0

u-boot:2016.05

开发板:Mini2440

宿主机:Ubuntu 16.04.7 LTS

----------------------------------------------------------------------------------------------------------------------------

为实现目标嵌入式平台能够正常运行Qt程序,则需要在目标平台上部署Qt运行环境。

一、Qt编译和安装

1.1 Qt版本介绍

Qt的版本比较多,容易搞混。现分别介绍:

  • Qt/X11 :指用于Linux/Unix的版本。如:我们常用的qt-x11-opensource-src-4.5.3.tar.gz,它是用于PC机linux平台的Qt源码;
  • Qt Windows:指用于Windows的版本;
  • qt-everywhere:指(在配置时加上不同的参数)既可用于x86,也可用于ARM,如 qt-everywhere-opensource-src-4.7.0.tar.gz qt-everywhere-opensource-src-4.6.1.tar.gz ;从Qt4.6开始提供这种源码包;
  • Qt/Embedded:指用于ARM平台的版本。如 qt-embedded-linux-opensource-src-4.5.3.tar.gz z是用于嵌入式ARM的qt源码包; 从Qt4.1开始,Qt/Embedded改名为Qtopia Core,又从Qt4.4.1开始,Qtopia Core又改名为Qt for Embedded Linux,一般发行的源码包的名字叫做:qt-embeded-linux-xxxxxx,但是自动Qt4.6开始就不再提供这种源码包了,而是开始提供qt-everywhere源码包;
  • 1.2 qt-everywhere下载

    这里我们下载qt-everywhere,这里我们不去选择较新版本,主要由于新版本已经不支持ARMv4t架构了,我们下载5.6版本源码包即可。

    国内镜像站点下载地址:

  • https://download.qt.io/archive (官方)
  • University of Science and Technology of China (推荐,旧版本较全)
  • 清华大学开源软件镜像站
  • 在ubuntu服务器上下载程序包:

    root@zhengyang:/work/sambashare# cd tools
    root@zhengyang:/work/sambashare/tools# wget https://download.qt.io/new_archive/qt/5.6/5.6.0/single/qt-everywhere-opensource-src-5.6.0.tar.xz

    下载完后,解压程序包:

    root@zhengyang:/work/sambashare/tools# tar -xvf  qt-everywhere-opensource-src-5.6.0.tar.xz

    1.3 修改qmake.conf

    进入 qt-everywhere-opensource-src-5.6.0文件夹,针对Mini2440开发板,修改qmake.conf文件:

    root@zhengyang:/work/sambashare/tools# cd qt-everywhere-opensource-src-5.6.0/
    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0/# 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) # 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 load(qt_config)

    我们需要根据我们安装得交叉编译工具去修改,由于我之前安装的是 arm-linux-gcc 4.8.3

    所以这里我们需要按照我们安装的交叉编译工具来修改QMAKE_CC、QMAKE_CXX等配置项:需要指定全路径。

    # qmake configuration for building with arm-linux-gnueabi-g++ MAKEFILE_GENERATOR = UNIX CONFIG += incremental QMAKE_INCREMENTAL_STYLE = sublib Qt_QPA_DEFAULT_PLATFORM = linuxfb QMAKE_CFLAGS += -msoft- float - D__GCC_FLOAT_NOT_NEEDED # 由于硬件不支持浮点运算,所以采用软件模拟浮点运算 QMAKE_CXXFLAGS += -msoft- float - D__GCC_FLOAT_NOT_NEEDED # 由于硬件不支持浮点运算,所以采用软件模拟浮点运算 QMAKE_CXXFLAGS += - O0 # g++ 不优化 编译会很慢 QMAKE_CXXFLAGS -= - O1 QMAKE_CXXFLAGS -= - O2 QMAKE_CXXFLAGS -= - O3 QMAKE_CFLAGS += - O0 # gcc 不优化 QMAKE_CFLAGS -= - O1 QMAKE_CFLAGS -= - O2 QMAKE_CFLAGS -= - O3 include(.. /common/ linux.conf) include(.. /common/ gcc -base- unix.conf) include(.. /common/g++- unix.conf) # modifications to g ++ .conf QMAKE_CC = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi- gcc -march=armv4t -mtune= arm920t QMAKE_CXX = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi-g++ -march=armv4t -mtune= arm920t QMAKE_LINK = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi-g++ -march=armv4t -mtune= arm920t QMAKE_LINK_SHLIB = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi-g++ -march=armv4t -mtune= arm920t # modifications to linux.conf QMAKE_AR = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi- ar cqs QMAKE_OBJCOPY = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi- objcopy QMAKE_NM = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi-nm - P QMAKE_STRIP = /usr/local/arm/ 4.8 . 3 /bin/arm-none-linux-gnueabi- strip load(qt_config)

    1.4 配置安装

    1.4.1 CMake安装

    CMake是一个跨平台的构建工具,其支持程度要好于qmake。CMake的配置更加灵活、强大,也更容易维护。如果是Qt6.0+需要安装CMake,否则忽略即可。

    注:是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。

    接着回到安装目录,安装CMake:

    root@zhengyang:/work/sambashare# cd /work/sambashare/tools
    root@zhengyang:/work/sambashare/tools# wget https://github.com/Kitware/CMake/releases/download/v3.21.2/cmake-3.21.2.tar.gz
    root@zhengyang:/work/sambashare/tools# tar xf cmake-3.21.2.tar.gz
    root@zhengyang:/work/sambashare/tools# cd cmake-3.21.2
    root@zhengyang:/work/sambashare/tools/cmake-3.21.2# ./configure
    root@zhengyang:/work/sambashare/tools/cmake-3.21.2# make && make install
    root@zhengyang:/work/sambashare/tools/cmake-3.21.2# cd ..
    root@zhengyang:/work/sambashare/tools# rm -rf cmake-3.21.2

    这里我们没有指定安装路径,默认是安装到了 /usr/local/bin路径。

    root@zhengyang:/work/sambashare/tools# ll  /usr/local/bin
    总用量 47556
    drwxr-xr-x  2 root root     4096 5月   7 13:45 ./
    drwxr-xr-x 19 root root     4096 5月   7 13:48 ../
    -rwxr-xr-x  1 root root 11319992 5月   7 13:45 ccmake*
    -rwxr-xr-x  1 root root 11589232 5月   7 13:45 cmake*
    -rwxr-xr-x  1 root root 12030672 5月   7 13:45 cpack*
    -rwxr-xr-x  1 root root 13098200 5月   7 13:45 ctest*
    -rwxr-xr-x  1 root root   230408 8月  27  2022 ffmpeg*
    -rwxr-xr-x  1 root root   123424 8月  27  2022 ffplay*
    -rwxr-xr-x  1 root root   139168 8月  27  2022 ffprobe*
    -rwxr-xr-x  1 root root   136720 8月  27  2022 ffserver*
    -rwxr-xr-x  1 root root     1568 8月  27  2022 sdl2-config*
    1.4.2 tslib安装

    要想Qt 支持触摸需要编译tslib ,以生成触摸相关插件。 tslib 多用于嵌入式系统中,是基本的触摸插件。 在上一节 linux设备树-LCD触摸屏设备驱动 已经介绍了tslib的安装,这里不重复介绍了,当时我们将tslib安装到了ls /work/sambashare/drivers/tslib/tmp/路径下。

    我们将其拷贝到/usr/local/tslib路径下:

    root@zhengyang:/work/sambashare# ls drivers/tslib/tmp/
    bin/     etc/     include/ lib/     share/
    root@zhengyang:/work/sambashare# cp drivers/tslib/tmp/* /usr/local/tslib/ -rfd
    
    
    
    
        
    
    1.4.3 Qt安装

    接着回到Qt安装目录:

    root@zhengyang:/work/sambashare# cd tools/qt-everywhere-opensource-src-5.6.0
    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# sudo mkdir -p /usr/local/qt5.6

    接下来配置Qt, 在Qt的源码目录下有一个可执行程序 configure, 运行./configure --help 可以看到详细的配置选项。

    为了操作方便,可以写一个脚本文件autoconfigure.sh,文容如下:

    sudo ./configure -prefix /usr/local/qt5.6 \
    -v \
    -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 

    -I和-L分别指定头文件目录和库目录,在安装tslib生成的目录tmp中,这里提前将tmp目录复制到/usr/local/tslib中。

    赋予配置脚本autoconfigure.sh 可执行权限,然后执行

    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# sudo apt-get install g++  #配置前请先安装g++,如已安装可忽略
    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# chmod +x autoconfigure.sh
    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# ./autoconfigure.sh 

    配置脚本运行完成之后,就可以进行编译和安装了,大约需要十几到几十分钟:

    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# make -j4
    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# make install

    注意:make -j4编译时间较长,而且可能出现各种问题,我们先把一些库装下来(不管它有用没用),不然一make就是半小时,实在没那个精力去试哪个没用,建议全部安装。

    root@zhengyang:/work/sambashare# sudo apt-get install lib32z1
    root@zhengyang:/work/sambashare# sudo apt-get install lib32ncurses5
    root@zhengyang:/work/sambashare# sudo apt-get install libncurses5-dev libncursesw5-dev
    root@zhengyang:/work/sambashare# sudo apt-get install lib32stdc++6
    root@zhengyang:/work/sambashare# sudo apt-get install libc6-dev
    root@zhengyang:/work/sambashare# sudo apt-get install libqt5serialport5-dev libudev-dev
    root@zhengyang:/work/sambashare# sudo apt-get install dbus
    root@zhengyang:/work/sambashare# sudo apt-get install libjpeg-dev

    安装完成后查看安装的文件夹:

    root@zhengyang:/work/sambashare/tools/qt-everywhere-opensource-src-5.6.0# ls /usr/local/qt5.6
    bin  doc  include  lib  mkspecs  plugins  qml  translations

    1.5 打包

    将 qt5.6文件夹拷贝到根文件系统所在目录,以备移植开发板时使用:

    root@zhengyang:/work/sambashare# cd /usr/local
    root@zhengyang:/usr/local# cp -rfd qt5.6 qt5.6-1    #建立一个副本
    root@zhengyang:/usr/local/qt5.6# cd qt5.6
    root@zhengyang:/usr/local/qt5.6# rm -rf doc include bin mkspecs qml translations
    root@zhengyang:/usr/local/qt5.6# cd ..
    root@zhengyang:/usr/local# mkdir -p /work/nfs_root/rootfs/usr/local/
    root@zhengyang:/usr/local# cp -rfd qt5.6 /work/nfs_root/rootfs/usr/local/    #拷贝到根文件系统/usr/local/qt5.6下
    root@zhengyang:/usr/local# rm -rf qt5.6 && mv qt5.6-1 qt5.6 #删除库目录并将副本名字改回来

    不能直接将lib和plugins目录复制到根文件系统中,这样制作出根文件系统后文件太大,一般会超过了SDRAM的大小64M,uboot烧写文件系统的程序是一次将程序完整读到内存再烧写的,所以无法烧写到Nand Flash。如果用NFS启动当然就没有这些问题。

    root@zhengyang:/usr/local# ls -l /work/nfs_root/rootfs/usr/local/qt5.6/
    总用量 16
    drwxr-xr-x  5 root root 12288 5月   7 18:30 lib
    drwxr-xr-x 15 root root  4096 5月   7 18:30 plugins

    注意:我的根文件系统存放在/work/nfs_root/rootfs文件夹,有关根文件系统的搭建参考 Mini2440之linux内核移植之yaffs2根文件系统移植

    1.6 配置环境变量

    最后在根文件系统添加Qt的环境变量:

    root@zhengyang:/usr/local# vim /work/nfs_root/rootfs/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=240x320:offset=0x0:tty=/dev/tty1
    export Qt_QPA_FB_TSLIB=1
    export LD_PRELOAD=/lib/preloadable_libiconv.so

    这里在根文件系统中配置了Qt的安装路径、库函数路径等。 最后一行配置了preloadable_libiconv.so,libiconv是一个常用的编码转换库,支持常用的多种编码之间的转换。在Linux下,工具链gcc有专门的libiconv库,所有不用移植,但在arm-linux下就没那么幸运了,需要我们额外移植libiconv库,不过,过程还是比较简单的。

    1.7 libiconv库安装

    1.7.1 下载源码
    root@zhengyang:/work/sambashare# cd /work/sambashare/tools/
    root@zhengyang:/work/sambashare/tools# wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
    root@zhengyang:/work/sambashare/tools# mkdir -p /usr/local/libiconv
    root@zhengyang:/work/sambashare/tools# tar xzvf libiconv-1.14.tar.gz
    1.7.2 配置

    进入源码进行配置:

    root@zhengyang:/work/sambashare/tools# cd libiconv-1.14
    root@zhengyang:/work/sambashare/tools/libiconv-1.14# CC=arm-linux-gcc ./configure --host=arm-linux --prefix=/usr/local/libiconv  CFLAGS="-march=armv4t -O2 -Wall -W" --enable-static
    1.7.3 编译安装
    root@zhengyang:/work/sambashare/tools/libiconv-1.14# make 

    编译出现如下错误:

    In file included from progname.c:26:0:
    ./stdio.h:1010:1: error: 'gets' undeclared here (not in a function)
     _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
    Makefile:914: recipe for target 'progname.o' failed
    make[2]: *** [progname.o] Error 1
    make[2]: Leaving directory '/work/sambashare/tools/libiconv-1.14/srclib'
    Makefile:865: recipe for target 'all' failed

    在本目录中执行: vim srclib/stdio.in.h文件,接着搜索下面这一行:

    _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");

    然后把这个替换成:

    #if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
    _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
     #endif

    重新编译安装:

    root@zhengyang:/work/sambashare/tools/libiconv-1.14# make
    root@zhengyang:/work/sambashare/tools/libiconv-1.14# make install
    root@zhengyang:/work/sambashare/tools/libiconv-1.14# cd /usr/local/libiconv/lib
    /usr/local/libiconv/lib# cp preloadable_libiconv.so /work/nfs_root/rootfs/lib    #拷贝到文件系统

    二、 安装Qt Creator

    2.1 下载安装包

    下载Qt Creator 5.6到Ubuntu中:

    root@zhengyang:/usr/local# cd /work/sambashare/tools
    root@zhengyang:/work/sambashare/tools# wget https://download.qt.io/new_archive/qt/5.6/5.6.0/qt-opensource-linux-x64-5.6.0.run

    qt-opensource-linux-x64-5.6.0.run为Linux安装包,由于官网下载较慢,可以通过CSDN下载 5.6.2版本

    2.2 修改权限并安装

    需要在ubuntu桌面环境,打开终端运行:

    zhengyang@zhengyang:/work/sambashare/tools$ sudo chmod 777 qt-opensource-linux-x64-5.6.0.run
    zhengyang@zhengyang:/work/sambashare/tools$ sudo ./qt-opensource-linux-x64-5.6.0.run

    按回车键执行安装命令后,弹出软件安装界面,如下所示:

    点击下一步,弹出界面如下所示,此界面可不设置,直接点击Skip按钮:

    一直下一步,直到安装完成,如下图所示:

    安装完成后,输入如下命令,打开Qt Creator的开发界面:

    zhengyang@zhengyang:/work/sambashare/tools$ cd /opt/Qt5.6.0/Tools/QtCreator/bin/
    zhengyang@zhengyang:/opt/Qt5.6.0/Tools/QtCreator/bin$ ls
    qbs         qbs-config-ui  qbs-setup-android  qbs-setup-toolchains  qtcreator
    qbs-config  qbs-qmltypes   qbs-setup-qt       qt.conf               qtcreator.sh
    zhengyang@zhengyang:/opt/Qt5.6.0/Tools/QtCreator/bin$ sudo ./qtcreator

    2.3 配置

    点击【工具】-【选项】:

    2.3.1 编译器

    点击左侧【构建和运行】,选择【编译器】,添加GCC编译器:

    名字输入:arm-linux-gcc 4.8.3;

    编译器路径输入:/usr/local/arm/4.8.3/bin/arm-none-linux-gnueabi-c++;

    2.3.2 Qt Vsersions

    点击左侧【构建和运行】,选择【Qt Versions】,手动设置qmake路径配置为:/usr/local/qt5.6/bin/qmake;

    2.3.3 构建套件

    点击左侧【构建和运行】,选择【构建套件(Kit)】,添加套件:

    名字输入:Mini2440 Qt 5.6.0 GCC 32bit;

    编译器选择:arm-linux-gcc 4.8.3;

    以后创建项目时Kit选择Mini2440 Qt 5.6.0 GCC 32bit就可以了。

    三、Qt应用程序测试

    3.1 示例教程

    我们直接选择一个示例教程,如图所示:

    接着选择Mini2440 Qt 5.6.0 GCC 32bit,点击Configure Project:

    点击菜单栏的【构建】,前后分别点击【执行qmake】 和【重新构建项目digitalclock】:

    构建完成后,会在 /opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock 工程目录文件夹所在目录下中生成可执行为文件,将其复制相应程序到根文件目录中。

    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qttools/designer# cd /opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock
    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock# ls -l
    总用量 2168
    -rwxr-xr-x 1 root root 807819 5月   8 19:21 digitalclock
    -rw-rw-r-- 1 root root   2626 3月   3  2016 digitalclock.cpp
    -rw-rw-r-- 1 root root   2251 3月   3  2016 digitalclock.h
    -rw-r--r-- 1 root root 674604 5月   8 19:21 digitalclock.o
    -rw-rw-r-- 1 root root    212 3月   3  2016 digitalclock.pro
    -rw-r--r-- 1 root root  23727 5月   8 19:20 digitalclock.pro.user
    -rw-rw-r-- 1 root root   2195 3月   3  2016 main.cpp
    -rw-r--r-- 1 root root 299608 5月   8 19:21 main.o
    -rw-r--r-- 1 root root  54434 5月   8 19:21 Makefile
    -rw-r--r-- 1 root root   3350 5月   8 19:21 moc_digitalclock.cpp
    -rw-r--r-- 1 root root 323648 5月   8 19:21 moc_digitalclock.o
    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock# cp digitalclock /work/nfs_root/rootfs/

    3.2 运行测试

    我们给开发板上电,等内核启动完成后, 运行如下命令:

    [root@zy:/]# ./digitalclock
    digitalclock (56): undefined instruction: pc=(ptrval)
    CPU: 0 PID: 56 Comm: digitalclock Not tainted 5.2.8 #31
    Hardware name: Samsung S3C2440 (Flattened Device Tree)
    PC is at 0xb601b7d0
    LR is at 0xb5fe99dc
    pc : [<b601b7d0>]    lr : [<b5fe99dc>]    psr: a0000010
    sp : bee6ebd8  ip : b601b798  fp : 00000000
    r10: 00000000  r9 : 00000007  r8 : bee6ec5c
    r7 : 00010100  r6 : 00000100  r5 : 00000000  r4 : b603b128
    r3 : 00001498  r2 : bee6ec5c  r1 : bee6ec54  r0 : b604edf0
    Flags: NzCv  IRQs on  FIQs on  Mode USER_32  ISA ARM  Segment user
    Control: c000717f  Table: 32d10000  DAC: 00000055
    Code: e3500000 0a000022 e59f70e8 e3a06c01 (ee070fba)
    Illegal instruction

    很不幸的是,程序运行失败了。竟然报了一个非法指令,那我们通过如下命令查看可执行文件的平台属性信息:

    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock# arm-linux-readelf -A digitalclock
    Attribute Section: aeabi
    File Attributes
      Tag_CPU_name: "4T"
      Tag_CPU_arch: v4T
      Tag_ARM_ISA_use: Yes
      Tag_THUMB_ISA_use: Thumb-1
      Tag_ABI_PCS_wchar_t: 4
      Tag_ABI_FP_rounding: Needed
      Tag_ABI_FP_denormal: Needed
      Tag_ABI_FP_exceptions: Needed
      Tag_ABI_FP_number_model: IEEE 754
      Tag_ABI_align_needed: 8-byte
      Tag_ABI_align_preserved: 8-byte, except leaf SP
      Tag_ABI_enum_size: int

    这里看到的可执行文件arch也是armv4t架构,那就奇怪了。实在没办法了,我们只能去排查到底是哪个指令非法了。

    3.2.1 非法指令异常排排查

    我们直接在内核代码搜索:

    root@zhengyang:/work/sambashare/linux-5.2.8-dt# grep "undefined instruction: pc=" * -nR
    匹配到二进制文件 arch/arm/kernel/traps.o
    arch/arm/kernel/traps.c:478:            pr_info("%s (%d): undefined instruction: pc=%p\n",
    我们定位到arch/arm/kernel/traps.c 中找到相关的异常处理函数do_undefinstr,其中部分代码为:
    #ifdef CONFIG_DEBUG_USER
            if (user_debug & UDBG_UNDEFINED) {
                    pr_info("%s (%d): undefined instruction: pc=%p\n",
                            current->comm, task_pid_nr(current), pc);
                    __show_regs(regs);
                    dump_instr(KERN_INFO, regs);
    #endif

    通过上面的代码我们如果CONFIG_DEBUG_USER 定义了,并且user_debug设置了参数,应该可以看到系统打印是哪个程序产生了异常。 通过kernel的.config文件发现 CONFIG_DEBUG_USER已经定义了。 user_debug是一个命令行参数。打开的方法为在uboot启动参数bootargs添加 user_debug=31。

    之前我们已经配置这些了,所以输出了PC信息。可以看到错误 pc=0xb601b7d0,未定义的指令 e e070fba 内核的地址范围为 c0000000 ~ffffffff,而 0xb601b7d0很明显不属于内核空间。

    进入Qt应用程序目录 ,输入命令如下命令将目标文件反汇编:

    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock# arm-none-linux-gnueabi-objdump -D -S digitalclock > dump.dis
    root@zhengyang:/opt/Qt5.6.0/Examples/Qt-5.6/qtbase/widgets/widgets/digitalclock# ls -l dump.dis
    -rw-r--r-- 1 root root 9605344 5月   8 19:38 dump.dis

    打开dump.dis文件,并没有定位到ee070fba指令,参考网上文章目前也没找到原因,等后面学了arm-linux-gdb远程调试再回过来排查。

    [1] 移植Qt5.6到JZ2440

    [2] 一、搭建通用Arm平台的Qt交叉编译环境

    [3] 嵌入式Linux下的Qt环境搭建

    [4] 嵌入式Linux--交叉编译安装Qt5.12.9

    [5] Qt下载(多种下载通道+所有版本)

    [6] ARM(S3C2440 )下解决的非法指令问题(Illegal instruction)

    [7] 法指令(Illegal Instruction)问题定位

    [8] https://doc.qt.io/qt-6/linux.html