linux GUI-QT6.5移植到Mini2440

Posted 大奥特曼打小怪兽

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux GUI-QT6.5移植到Mini2440相关的知识,希望对你有一定的参考价值。

----------------------------------------------------------------------------------------------------------------------------
内核版本:linux 5.2.8
根文件系统:busybox 1.25.0
u-boot:2016.05
开发板:Mini2440
----------------------------------------------------------------------------------------------------------------------------

为实现目标嵌入式平台能够正常运行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.gzqt-everywhere-opensource-src-4.6.1.tar.gz;从Qt4.6开始提供这种源码包;
  • Qt/Embedded:指用于ARM平台的版本。如qt-embedded-linux-opensource-src-4.5.3.tar.gzz是用于嵌入式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.0版本即可。

国内镜像站点下载地址:

在ubuntu服务器上下载程序包: 

 

root@zhengyang:/work/sambashare# cd tools
root@zhengyang:/work/sambashare/tools# wget https://download.qt.io/archive/qt/5.0/5.0.0/single/qt-everywhere-opensource-src-5.0.0.tar.xz

 

 

 

下载完后,解压程序包:

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

1.3 修改qmake.conf

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

 

root@zhengyang:/work/sambashare/tools# cd  qt-everywhere-opensource-src-5.0.0/
root@zhengyang:/work/sambashare/tools/qt-everywhere-src-6.0.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 -march=armv4t -mtune=arm920t
QMAKE_CXXFLAGS += -msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t

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
QMAKE_CXX               = /usr/local/arm/4.8.3/bin/arm-none-linux-gnueabi-g++
QMAKE_LINK              = /usr/local/arm/4.8.3/bin/arm-none-linux-gnueabi-g++
QMAKE_LINK_SHLIB        = /usr/local/arm/4.8.3/bin/arm-none-linux-gnueabi-g++

# 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.0.0
root@zhengyang:/work/sambashare/tools/ qt-everywhere-opensource-src-5.0.0# sudo mkdir -p /usr/local/Qt5.12

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

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

 

sudo ./configure -prefix /usr/local/Qt5.12 \\
-opensource \\
-confirm-license \\
-release \\
-strip \\
-shared \\
-xplatform linux-arm-gnueabi-g++ \\
-optimized-qmake \\
-c++std c++11 \\
--rpath=no \\
-pch \\
-skip qt3d \\
-skip qtactiveqt \\
-skip qtandroidextras \\
-skip qtcanvas3d \\
-skip qtconnectivity \\
-skip qtdatavis3d \\
-skip qtdoc \\
-skip qtgamepad \\
-skip qtlocation \\
-skip qtmacextras \\
-skip qtnetworkauth \\
-skip qtpurchasing \\
-skip qtremoteobjects \\
-skip qtscript \\
-skip qtscxml \\
-skip qtsensors \\
-skip qtspeech \\
-skip qtsvg \\
-skip qttools \\
-skip qttranslations \\
-skip qtwayland \\
-skip qtwebengine \\
-skip qtwebview \\
-skip qtwinextras \\
-skip qtx11extras \\
-skip qtxmlpatterns \\
-make libs \\
-make examples \\
-nomake tools -nomake tests \\
-gui \\
-widgets \\
-dbus-runtime \\
--glib=no \\
--pcre=qt \\
--zlib=qt \\
-no-openssl \\
--freetype=qt \\
--harfbuzz=qt \\
-no-opengl \\
-linuxfb \\
--xcb=no \\
-tslib \\
--libpng=qt \\
--libjpeg=qt \\
--sqlite=qt \\
-plugin-sql-sqlite \\
-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.0.0# sudo apt-get install g++  #配置前请先安装g++,如已安装可忽略
root@zhengyang:/work/sambashare/tools/ qt-everywhere-opensource-src-5.0.0# chmod +x autoconfigure.sh
root@zhengyang:/work/sambashare/tools/ qt-everywhere-opensource-src-5.0.0# ./autoconfigure.sh 

 

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

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

 

 

二、根文件系统制作

三、QT应用程序测试

参考文章

[1]移植QT5.6到JZ2440

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

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

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

 

正点原子I.MX6U-MINI移植篇kernel移植过程详解

一、下载Linux内核

这里使用NXP官方提供的Linux源码,将其移植到正点原子I.MX6U-MINI开发板上。NXP官方原版Liux源码路径为:1、例程源码->4、NXP官方原版Uboot和Linux->linux-imx-rel_imx4.1.15_2.1.0_ga.tar.bz2

在ubunut中的/home/zhiguoxin/linux/IMX6ULL/目录下创建一个nxp_kernel文件夹用于存放NXP的内核。使用FileZilla将其发送到Ubuntu中并解压,得到名为linux-imx-rel_imx4.1.15_2.1.0_ga的目录。

cd /home/zhiguoxin/linux/IMX6ULL/
mkdir nxp_kernel
cd nxp_kernel
tar -vxjf linux-imx-rel_imx_4.1.15_2.1.0_ga.tar.bz2

二、NXP官方开发板Linux内核编译

NXP提供的Linux源码肯定是可以在自己的I.MX6ULL EVK开发板上运行下去的,所以我们肯定是以I.MX6 ULL EVK开发板为参考,然后将Linux内核移植到I.MX6U-ALPHA开发板上的。

2.1 修改顶层Makefile

修改顶层Makefile,直接在顶层Makefile文件里面定义ARCH和CROSS COMPILE这两个的变量值为armarm-linux-gnueabihf-,结果如图所示:

2.2 配置并编译Linux内核

在编译 Linux 内核之前要先配置 Linux 内核。每个板子都有其对应的默认配置文件,这 些默认配置文件保存 在 arch/arm/configs 目录中。

imx_v7_defconfig 和imx_v7_mfg_defconfig 都可作为 I.MX6ULL EVK 开发板所使用的默认配置文件。但是这里建议使用 imx_v7_mfg_defconfig 这个默认配置文件,首先此配置文件默认支持 I.MX6UL 这款芯片,而且重要的一点就是此文件编译出来的 zImage 可以通过 NXP 官方提供的 MfgTool 工具烧写!!imx_v7_mfg_defconfig 中的“mfg”的意思就是 MfgTool。

进入到 Ubuntu 中的 Linux 源码根目录下,执行如下命令配置 Linux 内核:

make clean  //第一次编译 Linux 内核之前先清理一下
make imx_v7_mfg_defconfig //配置 Linux 内核

配置完成以后就可以编译了,使用如下命令编译 Linux 内核:

make -j16  //编译 Linux 内核

等待编译完成,结果如图所示:

Linux 内核编译完成以后会在arch/arm/boot 目录下生成zImage镜像文件,如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件,比如imx6ull-14x14-evk.dtb就是 NXP 官方的I.MX6ULL EVK开发板对应的设备树文件。至此我们得到两个文件:

  • ①、Linux内核镜像文件:zImage
  • ②、NXP官方 I.MX6ULL EVK开发板对应的设备树文件:imx6ull-14x14-evk.dtb

2.3 Linux内核启动测试

在上面已经得到了 NXP 官方I.MX6ULL EVK 开发板对应的 zImage和imx6ull-14x14-evk.dtb 这两个文件。这两个文件能不能在正点原子的 I.MX6U-ALPHA EMMC 版开发板上启动呢?测试一下不就知道了。

在测试之前确保 uboot 中的环境变量bootargs内容如下:

console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw

使用命令

setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv

将上一小节编译出来的zImage和imx6ull-14x14-evk.dtb复制到Ubuntu 中的tftp目录下,因为我们要在 uboot 中使用 tftp 命令将其下载到开发板中,拷贝命令如下:

cp arch/arm/boot/zImage /home/zhiguoxin/linux/tftp -f
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/zhiguoxin/linux/tftp -f

拷贝完成以后就可以测试了,启动开发板,进入uboot 命令行模式,然后输入如下命令将zImage 和 imx6ull-14x14-evk.dtb 下载到开发板中并启动:

tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000

可以看出,此时Linux内核已经启动了。

三、在Linux中添加自己的开发板

通过编译NXP官方I.MX6ULL EVK 开发板对应的Linux内核,发现其可以在正点原子的EMMC版本开发板启动,所以我们就参考I.MX6ULL EVK开发板的设置,在Linux内核中添加正点原子的I.MX6U-ALPHA开发板。

3.1 添加开发板默认配置文件 件

将 arch/arm/configs目录下的imx_v7_mfg_defconfig重新复制一份 , 命名 为imx_alientek_emmc_defconfig,命令如下:

cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig

以后imx_alientek_emmc_defconfig就是正点原子的EMMC版开发板默认配置文件了。完成以后如图所示:

以后就可以使用如下命令来配置正点原子EMMC版开发板对应的Linux内核了:

make imx_alientek_emmc_defconfig

3.2 添加开发板对应的设备树文件

添加适合正点原子 EMMC 版开发板的设备树文件,进入目录 arch/arm/boot/dts 中,复制一份 imx6ull-14x14-evk.dts,然后将其重命名为 imx6ull-alientek-emmc.dts,命令如下:

cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts

.dts是设备树源码文件,编译Linux的时候会将其编译为.dtb文件。imx6ull-alientek-emmc.dts创建好以后我们还需要修改文件arch/arm/boot/dts/Makefile, 找 到 “dtb-$(CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-alientek-emmc.dtb” ,如下所示:

第422行为“imx6ull-alientek-emmc.dtb”,这样编译Linux 的时候就可以从 imx6ull-alientek-emmc.dts编译出 imx6ull-alientek-emmc.dtb文件了。

3.3 编译测试

创建一个编译脚本,imx6ull_alientek_emmc.sh,脚本内容如下:

touch imx6ull_alientek_emmc.sh
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

  • 第2行,清理工程。
  • 第3行,使用默认配置文件imx_alientek_emmc_defconfig来配置Linux内核。
  • 第4行,打开Linux的图形配置界面,如果不需要每次都打开图形配置界面可以删除此行。
  • 第5行,编译Linux。

执行shell脚本 imx6ull_alientek_emmc.sh编译Linux内核,命令如下:

chmod 777 imx6ull_alientek_emmc.sh //给予可执行权限
./imx6ull_alientek_emmc.sh //执行 shell 脚本编译内核

编译完成以后就会在目录arch/arm/boot下生成zImage镜像文件。在arch/arm/boot/dts目录下生成 imx6ull-alientek-emmc.dtb文件。将这两个文件拷贝到tftp目录下,

cp arch/arm/boot/zImage /home/zhiguoxin/linux/tftp -f
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/zhiguoxin/linux/tftp -f

然后重启开发板,在uboot命令模式中使用tftp命令下载这两个文件并启动,命令如下:

tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 8080000083000000

只要出现如图 所示内容就表示 Linux 内核启动成功:

Linux内核启动成功,说明我们已经在NXP提供的 Linux内核源码中添加了正点原子I.MX6UL-MINI开发板。

四、CPU主频和网络驱动修改

4.1 CPU主频修改

正点原子I.MX6U-MINI开发板所使用的 I.MX6ULL 芯片主频都是792MHz 的,也就是NXP官方宣传的800MHz版本。

1 、设置 I.MX6U-MINI开发板工作在792MHz

确保EMMC中的根文件系统可用!然后重新启动开发板,进入终端(可以输入命令),输入如下命令查看cpu信息:

cat /proc/cpuinfo

结果如图所示:

在图中有BogoMIPS这一条,此时 BogoMIIS 为 3.00,BogoMIPS是Linux 系统中衡量处理器运行速度的一个“尺子”,处理器性能越强,主频越高,BogoMIPS 值就越大。

BogoMIPS只是粗略的计算CPU性能,并不十分准确。但是我们可以通过 BogoMIPS 值来大致的判断当前处理器的性能。在图中并没有看到当前 CPU 的工作频率,那我们就转变另一种方法查看当前CPU的工作频率。

进入到目录/sys/bus/cpu/devices/cpu0/cpufreq中,此目录下会有很多文件,使用如下命令查看当前CPU频率:

cd /sys/bus/cpu/devices/cpu0/cpufreq
cat cpuinfo_cur_freq

4.2 使能8线EMMC驱动

正点原子EMMC版本核心板上的EMMC 采用的8位数据线,原理图如图所示:

Linux内核驱动里面 EMMC默是4线模式的,4线模式肯定没有8线模式的速度快,所以本节我们将EMMC的驱动修改为8线模式。

修改方法很简单,直接修改设备树即可,打开文件 imx6ull-alientek-emmc.dts,找到如下所示内容:

cd arch/arm/boot/dts
vi imx6ull-alientek-emmc.dts
&usdhc2 
pinctrl-names = "default", "state_100mhz", "state_200mhz";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
bus-width = <8>;
non-removable;
status = "okay";
;

修改完成以后保存一下 imx6ull-alientek-emmc.dts,然后使用命令make dtbs重新编译一下设备树,编译完成以后使用新的设备树重启Linux 系统即可。

4.3 修改网络驱动

因为在后面学习Linux驱动开发的时候要用到网络调试驱动,所以必须要把网络驱动调试好。在讲解uboot移植的时候就已经说过了,正点原子开发板的网络和NXP官方的网络硬件上不同,网络PHY芯片由KSZ8081换为了 LAN8720A,两个网络 PHY芯片的复位IO也不同。所以Linux内核自带的网络驱动是驱动不起来I.MX6U-MINI开发板上的网络的,需要做修改。

4.3.1 修改LAN8720的复位以及网络时钟引脚驱动

ENET1复位引脚ENET1_RST连接在 I.M6ULL的SNVS_TAMPER7这个引脚上。ENET2的复位引脚 ENET2_RST 连接在I.MX6ULL 的SNVS_TAMPER8上。打开设备树文件imx6ull-alientek-emmc.dts,找到如下代码:

将 588 和 589 这两行删除掉!

删除掉以后继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码,将示例代码中的第 129 行和第 133 行处的代码删除掉!!否则会干扰到网络复位引脚!

在 imx6ull-alientek-emmc.dts 里面找到名为“iomuxc_snvs”的节点(就是直接搜索),然后在此节点下添加网络复位引脚信息,添加完成以后的“iomuxc_snvs”的节点内容如下:

    /*enet1 reset zhiguoxin*/
    pinctrl_enet1_reset: enet1resetgrp 
            fsl,pins = <
            /* used for enet1 reset */
            MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
        >;
    ;

    /*enet2 reset zhiguoxin*/
    pinctrl_enet2_reset: enet2resetgrp 
            fsl,pins = <
            /* used for enet2 reset */
            MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
        >;
    ;

第 1 行,imx6ull-alientek-emmc.dts 文件中 iomuxc_snvs 节点。
第 559~600 行,ENET1 网络复位引脚配置信息。
第 603~608 行,ENET2 网络复位引脚配置信息。

最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置,继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码


第 316和 331行,分别为 ENET1 和 ENET2 的网络时钟引脚配置信息,将这两个引脚的电气属性值改为0x4001b009,原来默认值为 0x4001b031。

修改完成以后记得保存一下 imx6ull-alientek-emmc.dts,网络复位以及时钟引脚驱动就修改好了。

4.3.2 修改fec1和fec2节点的pinctrl-0属性

在 imx6ull-alientek-emmc.dts 文件中找到名为“fec1”和“fec2”的这两个节点,修改其中的“pinctrl-0”属性值,修改以后如下所示:

4.3.3 修改LAN8720A的PHY地址

我们说过ENET1的LAN8720A地址为0x0,ENET2的LAN8720A地址为0x1。在 imx6ull-alientek-emmc.dts中找到如下代码:

  • 第 171 和 172 行,添加了 ENET1 网络复位引脚所使用的IO为GPIO5_IO07,低电平有效。复位低电平信号持续时间为 200ms。
  • 第 180 和 181 行,ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08,同样低电平有效,持续时间同样为 200ms。
  • 第 191 和 197 行,“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。
  • 第 190 行,注意“ethernet-phy@”后面的数字是 PHY 的地址,ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)。
  • 第 193 行,reg 的值也表示 PHY 地址,ENET1 的 PHY 地址为 0,所以 reg=0。
  • 第 196 行,ENET2 的 PHY 地址为 1,因此“@”后面为 1。
  • 第 199 行,因为 ENET2 的 PHY 地址为 1,所以 reg=1。
    至此,LAN8720A 的 PHY 地址就改好了,保存一下 imx6ull-alientek-emmc.dts 文件。然后使用“make dtbs”命令重新编译一下设备树。

4.3.4 修改fec_main.c文件

要在I.MX6ULL上使用LAN8720A, 需要修改一下Linux内核源码 ,打开
drivers/net/ethernet/freescale/fec_main.c,找到函数fec_probe,在 fec_probe中加入如下代码:

cd drivers/net/ethernet/freescale
vi fec_main.c
/* 设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK
* 这两个 IO 的复用寄存器的 SION 位为 1。
*/
void __iomem *IMX6U_ENET1_TX_CLK;
void __iomem *IMX6U_ENET2_TX_CLK;

IMX6U_ENET1_TX_CLK = ioremap(0X020E00DC, 4);
writel(0X14, IMX6U_ENET1_TX_CLK);

IMX6U_ENET2_TX_CLK = ioremap(0X020E00FC, 4);
writel(0X14, IMX6U_ENET2_TX_CLK);


第 3455~3462 就是新加入的代码,如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为1。

4.4.5 配置Linux内核,使能LAN8720驱动

输入命令“make menuconfig”,打开图形化配置界面,选择使能 LAN8720A 的驱动,路径如下:

-> Device Drivers
	-> Network device support
		-> PHY Device support and infrastructure
			-> Drivers for SMSC PHYs

选择将Drivers for SMSC PHYs编译到Linux内核中,因此<>里面变为了*。LAN8720A是SMSC公司出品的,因此勾选这个以后就会编译LAN8720驱动,配置好以后退出配置界面,然后重新编译一下Linux内核。

4.4.6 修改 smsc.c文件

在修改 smsc.c 文件之前先说点题外话,那就是我是怎么确定要修改 smsc.c 这个文件的。在写本书之前我并没有修改过 smsc.c 这个文件,都是使能 LAN8720A 驱动以后就直接使用。

但是我在测试 NFS 挂载文件系统的时候发现文件系统挂载成功率很低!老是提示NFS服务器找不到,三四次就有一次挂载失败!很折磨人。NFS 挂载就是通过网络来挂载文件系统,这样做的好处就是方便我们后续调试 Linux驱动。既然老是挂载失败那么可以肯定的是网络驱动有问题,网络驱动分两部分:内部MAC+外部 PHY,内部MAC驱动是由NXP提供的,一般不会出问题,否则的话用户早就给NXP反馈了。而且我用NXP官方的开发板测试网络是一直正常的,但是NXP官方的开发板所使用的PHY芯片为 KSZ8081。所以只有可能是外部PHY,也就是LAN8720A 的驱动可能出问题了。

鉴于LAN8720A 有“前车之鉴”,那就是在 uboot 中需要对LAN8720A 进行一次软复位,要设置 LAN8720A 的 BMCR(寄存器地址为 0)寄存器 bit15 为 1。所以我猜测,在 Linux 中也需要对 LAN8720A 进行一次软复位。

首先需要找到 LAN8720A 的驱动文件,LAN8720A 的驱动文件是 drivers/net/phy/smsc.c,在此文件中有个叫做 smsc_phy_reset 的函数,看名字都知道这是 SMSC PHY 的复位函数,因此,LAN8720A 肯定也会使用到这个复位函数,修改此函数的内容,修改以后的 smsc_phy_reset函数内容如下所示:

cd drivers/net/phy
vi smsc.c
static int smsc_phy_reset(struct phy_device *phydev)

    int err, phy_reset;
    int msec = 1;
    struct device_node *np;
    int timeout = 50000;

    if(phydev->addr == 0) /* FEC1 */
    
        np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@188000");

        if(np == NULL)
        
            return -EINVAL;
        
    

    if(phydev->addr == 1) /* FEC2 */
    
        np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@0b4000");

        if(np == NULL)
        
            return -EINVAL;
        
    

    err = of_property_read_u32(np, "phy-reset-duration", &msec);

    /* A sane reset duration should not be longer than 1s */
    if (!err && msec > 1000)
        msec = 1;

    phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);

    if (!gpio_is_valid(phy_reset))
        return;

    gpio_direction_output(phy_reset, 0);
    gpio_set_value(phy_reset, 0);
    msleep(msec);
    gpio_set_value(phy_reset, 1);

    int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);

    if (rc < 0)
        return rc;

    /* If the SMSC PHY is in power down mode, then set it
    * in all capable mode before using it.
    */
    if ((rc & MII_LAN83C185_MODE_MASK) ==
            MII_LAN83C185_MODE_POWERDOWN)
    

        /* set "all capable" mode and reset the phy */
        rc |= MII_LAN83C185_MODE_ALL;
        phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
    

    phy_write(phydev, MII_BMCR, BMCR_RESET);
    /* wait end of reset (max 500 ms) */

    do
    
        udelay(10);

        if (timeout-- == 0)
            return -1;

        rc = phy_read(phydev, MII_BMCR);
    
    while (rc & BMCR_RESET);

    return 0;

最后我们还需要在 drivers/net/phy/smsc.c 文件中添加两个头文件,因为修改后的smsc_phy_reset 函数用到了 gpio_direction_output 和gpio_set_value这两个函数,需要添加的头文件如下所示:

#include <linux/of_gpio.h>
#include <linux/io.h>

以上是关于linux GUI-QT6.5移植到Mini2440的主要内容,如果未能解决你的问题,请参考以下文章

Madplay移植到mini2440全过程具体解释

正点原子I.MX6U-MINI移植篇kernel移植过程详解

DM9000驱动移植在mini2440(linux2.6.29)和FS4412(linux3.14.78)上的实现(deep dive)篇一

正点原子I.MX6U-MINI移植篇u-boot移植过程详解

查看SUSE LINUX版本

正点原子I.MX6U-MINI移植篇rootfs移植过程详解