当先锋百科网

首页 1 2 3 4 5 6 7

书接上文,上次把U-Boot移植完成了,有兴趣的小伙伴可以通过传送门过去。

Linux系统的移植已经完成,但是果然还是移植没时间整理资料,没办法,2年级的娃真的很难辅导……

现在我对野火开发板的移植已经完成了纯净Linux系统、Busybox根文件系统、SDL+OpenGL、Python3.6,下一步开始移植音频、WIFI、蓝牙、以及按键系统,但是音频已经搞了两天了,移植找不到设备,看了无数遍源码,都无果,后来换上火哥提供的5月份的FullQt,依然是音频设备错误,技术客服回答可能是音频模块坏了,这两天会给我送一块新的板子来,希望一切顺利吧。

这篇里面先说说我的Linux和根文件系统的移植吧,以及关于Linux内核烧入eMMC和远程加载的几种方式,关于SDL的坎坷……先不挖坑了,有空再整理吧。

 

书归正传。

火哥提供的Linux没看,貌似集成的内容太多了,不够纯,因为我比较喜欢处,所以就从NXP官方已经准备好的系统开始移植吧。

其实NXP提供的系统源码基本是可以用的,要修改的东西比较少,那就直接动手烧录他的系统吧。

  • NXP官方系统烧录测试

NXP的系统可以从官网下载,或者从我提供的连接中下载都可以。

命令如下:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16

第一行命令用于清除工程中之前编译的残留文件,最好这样做,否则有惊喜。

第二行命令用于指定配置文件使用imx_v7_defconfig,这是EVK板子自带的东西。

第三行用于编译内核文件,时间比较长,尤其在虚拟机里做,你可以先吃杯泡面,回来就好了。

之后就编译出了Linux的内核文件,在arch/arm/boot中,如果存在zImage和imx6ull-14x14-evk.dtb两个文件表示成功,否则肯定是出问题了。我分析问题可能出现以下几种:

  1. 没有安装交叉编译环境,但如果你做了U-Boot移植,问题应该不在这;
  2. 没有安装lzop,直接apt-get安装一下即可;
  3. 配置文件名称写错了,imx_v7_defconfig;
  4. CROSS_COMPILE=arm-linux-gnueabihf- 后面没加空格,这个错误很低级。

如果两个文件都出来了,那么恭喜你,第一关过了。

下一步开始启动,启动前要保证几件事:

  1. 已经做好了U-Boot的移植,并且能够正常启动,如果不知道这是啥,去传送门看,先把U-Boot移植好了再回来看这个;
  2. 服务器端(Ubuntu或其他Linux端)安装了tftp或者nfs,关于这个教程这里不写了,问度娘吧。

用U-Boot启动NXP的Linux内核

先用tftp启动,把两个文件拷贝到tftp的目录下,启动tftp服务器。

启动U-Boot进入命令行模式,修改bootargs参数

setenv bootargs“console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw”

saveenv

设置U-Boot网络参数:

setenv ipaddr 192.168.1.55           //开发板IP地址

setenv ethaddr 00:04:9f:04:d2:35     //开发板网卡MAC地址

setenv gatewayip 192.168.1.1         //开发板默认网关

setenv netmask 255.255.255.0         //开发板子网掩码

setenv serverip 192.168.1.128         //服务器地址,也就是Ubuntu地址

saveenv                              //保存环境变量

然后尝试用tftp加载内核和设备树文件,并启动。

tftp 80800000 zImage

tftp 83000000 imx6ull-14x14-evk.dtb

bootz 80800000 - 83000000

前两行是通过tftp命令把服务器端的两个文件拉下来放到指定位置,Linux内核放在80800000,设备树放在83000000,6ULL默认从80000000启动,但是这个位置已经放了U-Boot,而且我们U-Boot加载Linux的时候还需要用,所以位置要往后放,这个参数根据自己的喜好设置吧。

或者通过nfs启动也成,先把两个文件放到NFS的目录下,命令如下:

nfs 80800000 192.168.31.128:/home/mars/Linux/nfs/zImage

nfs 83000000 192.168.31.128:/home/mars/Linux/nfs/imx6ull-14x14-evk.dtb

bootz 80800000 - 83000000

通过我测试,我的NFS要比TFTP快很多。

另外就是可以设置bootcmd参数,把启动命令自动化,这样就不用每次进U-Boot启动Linux系统了。

setenv bootcmd “nfs 80800000 192.168.31.128:/home/mars/Linux/nfs/zImage; nfs 83000000 192.168.31.128:/home/mars/Linux/nfs/imx6ull-14x14-evk.dtb;bootz 80800000 - 83000000”

记得用saveenv保存参数。

这里有个小插曲,我觉得是大家可能会才到的坑,就是NFS加载的时候会出现ERROR:File lookup fail的错误,这是因为uboot中使用的NFS版本是V2,而ubuntu的NFS版本为V3或V4及以上版本,导致uboot不能在NFS服务器中找到文件,所以需要修改ubuntu中NFS的兼容。

打开/etc/default/nfs-kernel-server文件,改三行内容:

RPCNFSDCOUNT="-V 2 8"

RPCMOUNTDOPTS="-V 2 --manage-gids"

RPCSVCGSSDOPTS="--nfs-version 2,3,4 --debug --syslog"

改完之后重启nfs就可以了。

Linux内核启动后控制台会蹦出一堆的内核加载信息,但到了最后发现加载不过去了,提示“Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)”,这是没有根文件系统造成的,这个先忽略,后面会讲到。到了这里表示你的原始内核已经移植成功了,吃杯泡面奖励一下自己吧。

  • 改造自己的Linux内核

这部分内容对于野火用户来说非常友好,因为野火的开发板基本参考了NXP官方的板子,要改的东西不是很多,也没有太深奥的地方,甚至比隔壁家的还好弄。

2.1 添加自己的开发板配置文件

配置之前,先用make distclean清理一下工程,否则看着太乱。

上一节中我们编译官方内核的时候使用的是imx_v7_defconfig这个配置,这个文件在arch/arm/configs中,我们直接复制一份,重命名为imx_embedfire_emmc_defconfig,这里面是一些模块配置项,后面在移植声卡网卡一类的东西的时候需要改动,在这我们先不动了,永远是的就可以。

复制设备树文件,Linux内核中所有的设备树都存放在arch/arm/boot/dts中,素有imx6ull-开头的都是关于我们这块CPU的设备树,也是NXP官方已经写好的东西,我们从imx6ull-14x14-evk.dts直接入手。

复制这个文件,改名为imx6ull-embedfire-emmc.dts,今后涉及到设备树修改的,都需要在这里进行,本小结中先不动丫。

设备树文件有了,我们还希望在Makefile中能够找到他。

打开arch/arm/boot/dts/Makefile文件,搜索一下dtb-$(CONFIG_SOC_IMX6ULL),在最下面加入我们设备树的名字即可,这样在进行编译的时候就会按照我们的设备树文件编译出imx6ull-embedfire-emmc.dtb文件了。

至此,配置文件基本全部搞定,重新编译并通过U-Boot远程启动测试一下。

记得,在编译的时候使用imx_embedfire_emmc_defconfig这个配置。

2.2 修改eMMC驱动

在Linux内核源码中,eMMC采用的是4线模式的,而野火iMX6ULL Pro开发板用的是8线的,不改变也能用,但既然人家提供了8车道,为啥还要在4车道堵车呢!改丫的!

打开imx6ull-embedfire-emmc.dtb设备树文件,找到&usdhc2标签,修改成一下内容:

pinctrl-names = "default" , "state_100mhz" , "state_200hmz";

pinctrl-0 = <&pinctrl_usdhc2_8bit>;

pinctrl-1 = <&pinctrl_usdhc2_8bit_100hmz>;

pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;

bus-width = <8>;

non-removable;

status = "okay";

2.3 修改LCD驱动

LCD是在硬件开发中比较常用的一种设备,在U-Boot移植的文章中,我们已经做了野火7寸LCD的移植,在Linux下,可以搭配SDL、QT这样的GUI库制作出精美的UI界面。

在Linux中,应用程序是需要通过操作LCD实现字符、图片等内容的显示,在裸机开发中我们可以随意分配一块内存给LCD作为显存用,但是在Linux中,系统对内存管理是很严格的,对于系统内存和用户内存有着明确的划分,正常情况下是不予许随意访问的,而在我们的LCD编程中,我们的驱动程序和应用程序都需要访问同一款叫做“显存”的虚拟内存实现绘制,所以为了解决这个问题,FrameBuffer应运而生,系统内核通过FrameBuffer对显存进行控制,对界面操作最终都是基于FB进行编程的。在Linux一切接文件的中心思想引领下,我们可以在/dev目录下找到显存对应的fbX的一系列文件,我们今天要做的LCD显示用的是/dev/fb0。

LCD的驱动有很多,NXP官方和野火及隔壁家的开发板都是使用的RGB888的协议,驱动NXP官方已经写好了,会在/dev下面生成一个fb0的设备,如果有多个显示设备的话还会出现fb1、fb2…。

过多的理论性内容网上一大堆,不啰嗦了,开始实战。

在Linux配置外设,无非就是操作设备树文件,对于相同协议的LCD,驱动基本上都是一样的,只需要根据不同的LCD硬件调整参数。在移植U-Boot的时候,对于LCD的移植已经讲得很清楚了,就是修改类似控制器hspw、hbp、hfp等等一些时间相关的参数。

打开imx6ull.dtsi文件,找到cdif:lcdif@021c8000这个节点,这里所有的配置项就是用于控制LCD显示的,这个节点在I.MX6ULL平台中是通用的,既然是通用也就意味着丫是不完整的,所以还需要我们在自己的imx6ull-embedfire-emmc.dts中做更进一步的配置。

我们先看imx6ull.dtsi文件中关于LCD节点的描述。compatible,这个字段在配置文件中是通用的,表示兼容性,LCD的兼容属性是"fsl,imx6ul-lcdif"和"fsl,imx28-cldi",在原文件中搜索就可以看到相关适配驱动的信息,有兴趣的可以读读源码。

打开imx6ull-embedfire-emmc.dts,找到pinctrl_lcdif_dat段,这部分是关于LCD用到引脚的配置,野火开发板和NXP开发板的引脚结构是相同的,所以这里基本不用改,而且建议大家以后做实际项目的时候尽量也用这些官方推荐的引脚。

第二个要修改的是&lcdif段,这里是关于LCD具体参数的配置,这里改的东西比较多,大部分需要根据你手头上用到的屏幕主板参数进行配置。

这里再次招来GT911的数据手册。

Item

Symbol

Values

Unit

Remark

Min.

Typ.

Max.

Horizontal Display Area

thd

-

800

-

DCLK

 

DCLK Frequency

fclk

26.4

33.3

46.8

MHz

 

One Horizontal Line

th

862

1056

1200

DCLK

 

HS pulse width

thpw

1

-

40

DCLK

 

HS Blanking

thb

46

46

46

DCLK

 

Vertical Display Area

tvd

-

480

-

TH

 

VS period time

tv

510

525

650

TH

 

VS pulse width

tvpw

1

-

20

TH

 

VS Blanking

tvb

23

23

23

TH

 

VS Front Porch

tvfp

7

22

147

 

 

 

  1. Pinctrl-0:这里面配置了引脚的具体情况,这里用不到复位,所以要删除pinctrl_lcdif_rest
  2. Bits-per-pixel:像素格式,我们采用的是RGB888的协议,所以宽度为24bit
  3. bus-width:线宽,根据自己板子的DATA信号线对应,野火7寸屏用的是DATA0~DATA23,所以我的是24线
  4. clock-frequency:像素时钟,搜侧重是33.3MHz,所以应该是33300000
  5. hactive:X轴像素数,800
  6. vactive:Y轴像素数
  7. hfront-porch,HFP,210
  8. hback-porch,HBP,46
  9. hsync-len,HSPW,1
  10. vback-porch,VBP,23
  11. vfront-porch,VFP,7
  12. vsync-len,VSPW,1
  13. hsync-active,HSYNC数据线极性,0
  14. vsync-active,VSYNC数据线极性,0
  15. de-active,DE数据线极性,1
  16. pixelclk-active,时钟数据线极性,0

这些参数设置好之后LCD就能正常显示了,如果出现花屏或者黑屏的情况,很有可能是某个参数写错了,尤其是宽高。

第二步就是配置背光。

NXP官方板子和野火用的都是GPIO1_IO08控制背光,所以关于pinctrl_pwm1这段也不需要修改,关于pwm1这个节点的信息,在imx6ull.dtsi文件中可以找到,如果找不到就直接在imx6ull-embedfire-emmc.dts中重写一个,尽量不要去改动imx6ull.dtsi,毕竟人家是通用的设备树信息。

在imx6ull-embedfire-emmc.dts文件中可找到&pwm1的段,status设置为okay启用背光,通过阅读Documentation/devicetree/indings/video/backlight/pwm-backlight.txt得知,节点backlight就是背光的设置段,compatible属性设置为pwm-backlight,对应的驱动文件是drivers/video/backlight/pwm_bl.c。背光的PWM频率官方推荐是5KHz,这个我们就不改他了,除非屏幕闪烁厉害。

brightness-levels属性描述了屏幕的亮度级别,原文件中只给出了几个值,我们把他扩展到0~255,0表示PWM占空比为0%,背光完全关闭,255表示背光占空比为100%,背光全亮。当然,这个值可以任意写,只要不超过255就行。

default-brightness-level表示当前亮度级别,随便设置啥都行,这个值表示的是brightness-levels的Index值。

调整完毕后重新编译,,启动新的内核,这时候如果屏幕上出现了小企鹅,恭喜你,LCD移植成功。

如果你的小企鹅没出来,看看menuconfig中Device Drivers -> Graphics support -> Bootup logo下面的三个选项是不是都选中了。

可以通过/sys/devices/platform/backlight/backlight/backlight下面的文件操作背光显示,需要注意的是,这个文件必须在开发板的系统下才能看到,在Ubuntu下是看不到这个文件系统的。当然,这是后话,因为这时候还没一直根文件系统涅。

这个目录下的max_brightness表示最大级别,也就是default-brightness-level的Index值,如果这里面我们设置了7个值,那max_brightness最大就是7,而不是255,不知道有没有表达清楚。

brightness表示当前的背光级别。

2.4 LCD的额外设置和LOGO修改

最喜欢的环节,改LOGO。

在你的Ubuntu系统中先装个软件爱你 netpbm,用apt-get可以直接下载安装。

做好你的LOGO,bmp和png都可以,然后用这个软件转换成ppm格式的。

具体命令如下:

bmptopnm rainbow.bmp > rainbow.pnm

pnmquant 224 rainbow.pnm > rainbow_224.pnm

pnmtoplainpnm rainbow_224.pnm > logo_linux_clut224.ppm

第一行可以换成pngtopnm,第二行命令要求源文件和目的文件不能重名,第三行尽量保持同名。

最后把 logo_linux_clut224.ppm复制到源码devices/video/logo/下替换原来的文件,并删除logo_linux_clut224.c和logo_linux_clut224.o。最好是在编译前清理一下工程,这样保证不会出问题。

这样LOGO就改成我们自己的了。

在U-Boot中,设置bootargs,加一个console=tty1的输出,即setenv bootargs 'console=tty1 console=ttymxc0,115200’,这样屏幕上就可以看到控制台输出内容了。

等移植完根文件系统之后,在修改etc/inittab文件,加入tty1::askfirst:-/bin/sh,这样我们的I.MX6ULL主板就可以接收到剪片的输入了。

在默认情况下,10分钟后LCD会黑屏,如果需要增长这个时间,或者是要设置永久亮屏,只需要修改源码drivers/tty/vt/vt.c文件中的blankinterval白能量即可,0表示常亮。

另外,进入系统后可以通过fbset查看屏幕的参数信息。

2.5 修改RTC

RTC也就是系统实时时钟,用于记录系统的时间,在野火I.MX6ULL Pro开发板上有一块纽扣电池专门用于在系统掉电后维持系统时间。而在Linux驱动中也已经写好了RTC的驱动程序,NXP已经帮我们最好了移植,所以这块我们就不用在动了,直接用就行。

进入系统后时间是错乱的,所以要通过date -s “2020-11-24 17:25:30”命令来设置系统时间,设置完毕后再用date命令查询时间,发现一切OK。

But,重启是否发现时钟有他娘的归零了!!

不要着急,吃桶泡面稳定一下情绪。

在date设置完之后,你还需要hwclock -w写入到RTC芯片中,这样你的时钟就保存下来了,而且他会自己运行。

Linux源码:https://download.csdn.net/download/suolong123/13507164

U-Boot移植:https://blog.csdn.net/suolong123/article/details/109905018