ZYNQ #1 - PL端模拟HDMI信号输出环境下的Linux界面显示

22 篇文章 3 订阅
9 篇文章 23 订阅

目录

0 - 前言

1 - petalinux工程的建立与配置

2 - 将解码驱动配置到linux内核中

3 - petalinux配置linux内核

4 - 修改设备树

5 - 编译打包

6 - 文件修改

6.1 - 开机启动rc.local并唤起图形桌面环境

6.2 - 指定X系统所使用的framebuffer设备

X - 附录 问题


0 - 前言

在前面的文章里(ZYNQ7000 #0 - petalinux的使用与工程建立),我们已经使用 petalinux 成功的配置了一个可以在板子上运行的linux系统环境。这篇文章中我们加上HDMI向外输出图像信号的功能。

我的开发板是黑金的AX7010,其附带的资料对于这方面讲解的不是很清楚,我也是通过翻找其教程中提到的 “使用Debian系统”附带的Debian根文件系统解决的在使用 startx 唤起 X 桌面环境后黑屏的问题。究其主要原因还是 需要对 X 桌面环境进行设置,要求其使用FrameBuffer进行绘制

AX7010这个开发板上虽然有HDMI-A的母头,但是其并没有板载HDMI芯片,而其对外输出HDMI信号的方式是利用PL端的IO对HDMI信号的时钟和数据进行模拟达到的。这里不过多的介绍关于其如何搭建PL端的方法,而重点关注如何在这样的环境中配置 X 桌面环境利用FrameBuffer进行图像绘制。

这里我们需要准备的是:

连接完后大致的框图如下:

1 - petalinux工程的建立与配置

petalinux工程的建立、从 .sdk 导入硬件工程配置、配置rootfs放置在SD卡 以及 配置使用外部linux源码的方法可以看这篇文章(ZYNQ7000 #0 - petalinux的使用与工程建立

 

2 - 将解码驱动配置到linux内核中

如果你使用的是petalinux 2019.1或者更高的版本,因为其linux使用的内核为4.19,其内部有部分函数进行了修改,需要将digilent_encoder中的

drm_mode_connector_update_edid_property(connector, edid);

替换为

drm_connector_update_edid_property(connector, edid);

具体参考 https://forums.gentoo.org/viewtopic-t-1088330-start-0.html

首先按照上述准备工作中的路径将 clk-fixed-factor.c 时钟驱动文件, digilent_encoder.c 视频解码驱动文件放置到Linux源码路径下。

  • 配置 clk-dglnt-dynclk

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/clk/Kconfig 将 clk-dglnt-dynclk.c 的配置项放入menuconfig中

config COMMON_CLK_DGLNT_DYNCLK
	tristate "Digilent axi_dynclk Driver"
	depends on ARCH_ZYNQ || MICROBLAZE
	help
	---help---
	  Support for the Digilent AXI Dynamic Clock core for Xilinx
	  FPGAs.

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/clk/Makefile 使得 clk-dglnt-dynclk.c 在menuconfig配置好后在linux编译时能编译。

obj-$(CONFIG_COMMON_CLK_DGLNT_DYNCLK)	+= clk-dglnt-dynclk.o

  • 配置 digilent_encoder

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/gpu/drm/xilinx/Kconfig,将 digilent_encoder.c 的配置项放入menuconfig中

config DRM_DIGILENT_ENCODER
	tristate "Digilent VGA/HDMI DRM Encoder Driver"
	depends on DRM_XILINX
	help
	  DRM slave encoder for Video-out on Digilent boards.

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/gpu/drm/xilinx/Makefile,使得 digilent_encoder.c 在menuconfig配置好后在linux编译时能编译。

obj-$(CONFIG_DRM_DIGILENT_ENCODER) += digilent_encoder.o

 

3 - petalinux配置linux内核

运行命令,配置内核

petalinux-config -c kernel

在 Device Drivers -> Graphics support,选择 Digilent VGA/HDMI DRM Encoder Driver 项按 y。

在 Device Drivers → Common Clock Framework 选项中选择 Digilent axi_dynclk Driver 按 y

保存退出

注意:这里不要修改默认的保存文件名 ( .config )

 

4 - 修改设备树

这里我是直接用的黑金写的设备树。

打开petalinux工程文件夹中 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi,刚生成petalinux的工程文件夹中,这个dtsi文件是空的,将其修改为以下内容。

/include/ "system-conf.dtsi"

/ {
	model = "Zynq ALINX Development Board";
	compatible = "alinx,zynq", "xlnx,zynq-7000";
	aliases {
		ethernet0 = "&gem0";
		serial0 = "&uart1";
	};

	usb_phy0: usb_phy@0 {
		compatible = "ulpi-phy";
		#phy-cells = <0>;
		reg = <0xe0002000 0x1000>;
		view-port = <0x0170>;
		drv-vbus;
	};


};

&i2c0 {
	clock-frequency = <100000>;
};

&usb0 {
	dr_mode = "host";	
	usb-phy = <&usb_phy0>;
};

&sdhci0 {
	u-boot,dm-pre-reloc;
};

&uart1 {
	u-boot,dm-pre-reloc;
};


&flash0 {
	compatible = "micron,m25p80", "w25q256", "spi-flash";
};


&gem0 {
	phy-handle = <&ethernet_phy>;
	ethernet_phy: ethernet-phy@1 {
		reg = <1>;
		device_type = "ethernet-phy";
	};
};



&amba_pl {

	hdmi_encoder_0:hdmi_encoder {
		compatible = "digilent,drm-encoder";
		digilent,edid-i2c = <&i2c0>;
	};

	xilinx_drm {
		compatible = "xlnx,drm";
		xlnx,vtc = <&v_tc_0>;
		xlnx,connector-type = "HDMIA";
		xlnx,encoder-slave = <&hdmi_encoder_0>;
		clocks = <&axi_dynclk_0>;
		dglnt,edid-i2c = <&i2c0>;
		planes {
			xlnx,pixel-format = "rgb888";
			plane0 {
				dmas = <&axi_vdma_0 0>;
				dma-names = "dma";
			};
		};
	};
};
&axi_dynclk_0 {
	compatible = "digilent,axi-dynclk";
	#clock-cells = <0>;
	clocks = <&clkc 15>;
};
&v_tc_0 {
	compatible = "xlnx,v-tc-5.01.a";
};

这里面最重要的部分是 amba_pl 下的 hdmi_encoder 和 xilinx_drm部分的设置

 

5 - 编译打包

用下面命令编译uboot、内核、根文件系统、设备树等

petalinux-build

用下面命令打包生成 BOOT.BIN 文件

petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga --u-boot --force

将生成的 BOOT.BIN 及 image.ub 拷贝到 SD 卡的FAT分区,根文件系统已放置到EXT分区

 

6 - 文件修改

 

6.1 - 开机启动rc.local并唤起图形桌面环境

在/etc/目录下建立 rc.local 文件,赋予其 +x 属性,然后在rc.local中添加

#!/bin/bash

#ifconfig eth0 up														#可选,唤起你的网卡
#dhclient	&																#可选,自带从dhcp获取ip地址

startx&
exit 0

这样,在linux启动后,会执行/etc/rc.local下的命令,即 startx

startx最终会调用/etc/X11/xinit/xinitrc下的命令

我们在X的配置文件(这里我用的是startx默认最终会选择的/etc/X11/xinit/xinitrc)修改如下

#!/bin/sh
# /etc/X11/xinit/xinitrc
#
# global xinitrc file, used by all X sessions started by xinit (startx)
# invoke global X session script

echo "LEE:xset turen off screensave DPMS"
xset s off																#关闭 X Screen Save
xset dpms 0 0 0														#关闭 DPMS
xset -dpms
          
xhost +  																	#允许任意host连接到x服务
          
export DISPLAY=:0.0 & /home/sements/developarea/qeyes/qeyes/qeyesArm64 &															#DISPLAY变量 并 #后台执行自己的一个小程序
        
#. /etc/X11/Xsession
openbox-session									#唤起 openbox

在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处. 直接登陆图形界面或者登陆命令行界面后使用startx启动图形, DISPLAY环境变量将自动设置为:0:0, 此时可以打开终端, 输出图形程序的名称(比如xclock)来启动程序, 图形将显示在本地窗口上

这里 xinitrc 中部分代码解释可以看这里: https://blog.csdn.net/sements/article/details/88123894

6.2 - 指定X系统所使用的framebuffer设备

为了让 X 界面系统启动时使用设定的framebuffer进行绘制,我们需要在相应配置文件中加入下面的语句:

Section "Device"  
  Identifier "myfb"
  Driver "fbdev"
  Option "fbdev" "/dev/fb0"
EndSection

有两种可选的加入位置。

  • 第一种在目录(/etc/X11/xorg.conf.d 没有这个目录就创建即可)下已有的 配置文件(如:40-libinput.conf )中加入上面的语句。

  • (推荐)第二种就是在目录(/etc/X11/xorg.conf.d 没有这个目录就创建即可)新建一个 .conf 文件,这里叫它 99-fbdev.conf (前面的数字影响着 X 界面系统启动加载这些配置文件时的顺序),然后在这个文件中加入上面的语句。

X - 附录 问题

在没有正确的配置 X 使用 Framebuffer进行绘制时,使用 startx 开启图形界面时可能出现以下错误

  • Failed to launch bus: Failed to connect to session bus
  • 唤醒了 X 但是黑屏
  • AddScreen/ScreenInit failed for driver 0
  • failed to load driver: xilinx_drm

 

救救穷学生,5毛买包托肥
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值