目录
0 - 前言
1 - petalinux工程的建立与配置
2 - 将解码驱动配置到linux内核中
3 - petalinux配置linux内核
4 - 修改设备树
5 - 编译打包
6 - 文件修改
X - 附录 问题
在前面的文章里(ZYNQ7000 #0 - petalinux的使用与工程建立),我们已经使用 petalinux 成功的配置了一个可以在板子上运行的linux系统环境。这篇文章中我们加上HDMI向外输出图像信号的功能。
我的开发板是黑金的AX7010,其附带的资料对于这方面讲解的不是很清楚,我也是通过翻找其教程中提到的 “使用Debian系统”附带的Debian根文件系统解决的在使用 startx 唤起 X 桌面环境后黑屏的问题。究其主要原因还是 需要对 X 桌面环境进行设置,要求其使用FrameBuffer进行绘制。
AX7010这个开发板上虽然有HDMI-A的母头,但是其并没有板载HDMI芯片,而其对外输出HDMI信号的方式是利用PL端的IO对HDMI信号的时钟和数据进行模拟达到的。这里不过多的介绍关于其如何搭建PL端的方法,而重点关注如何在这样的环境中配置 X 桌面环境利用FrameBuffer进行图像绘制。
这里我们需要准备的是:
连接完后大致的框图如下:
petalinux工程的建立、从 .sdk 导入硬件工程配置、配置rootfs放置在SD卡 以及 配置使用外部linux源码的方法可以看这篇文章(ZYNQ7000 #0 - petalinux的使用与工程建立)
如果你使用的是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源码路径下。
打开 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
打开 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
运行命令,配置内核
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 )
这里我是直接用的黑金写的设备树。
打开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 = <ðernet_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部分的设置
用下面命令编译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分区
这里我是之前建立ubuntu文件系统的时候就已经在该文件夹下加入了一个 40-libinput.conf(建立ubuntu文件系统参考这里https://blog.csdn.net/sements/article/details/88086468)
这里只是为了让 X 界面系统启动的时候设定利用framebuffer进行绘制,所以有两种可选的方法。第一种在该目录(/etc/X11/xorg.conf.d 没有这个目录就创建即可)下已有的 40-libinput.conf 配置文件中加入语句。第二种就是新建一个 .conf 文件,这里叫它 99-fbdev.conf (前面的数字影响着 X 界面系统启动加载这些配置文件时的顺序),然后在这个文件中加入语句。
Section "Device"
Identifier "myfb"
Driver "fbdev"
Option "fbdev" "/dev/fb0"
EndSection
/etc/X11/xinit/xinitrc 文件是在调用语句 startx 后回加载的脚本,这里我面进行了一些操作:
1.载入变量 "export DISPLAY=:0.0",
2.关闭了 X 桌面系统的电源管理和屏幕保护
3.加载了我自己写的一个有界面的小程序
4. 唤起openbox-session
#!/bin/sh
# /etc/X11/xinit/xinitrc
#
# global xinitrc file, used by all X sessions started by xinit (startx)
# invoke global X session script
#. /etc/X11/Xsession
export DISPLAY=:0.0
echo "TURN OFF DPMS"
xset s off
xset dpms 0 0 0
xset -dpms
/home/sements/developArea/RailTranser-Studio/RailTranser-Studio/RailTranser-Studio &
#xeyes&
openbox-session
这个文件是一种比较老旧的 Linux 开机启动自定义命令的方法,这个文件里面我做了一些操作
1.唤起 eth0 ,并使用 dhclient 自动获取 ip 地址
2.使用 startx 命令唤起 X 桌面系统(其运行后就会加载 /etc/X11/xinit/xinitrc 文件脚本和 /etc/X11/xorg.conf.d 下的本机配置项)
#!/bin/bash
ifconfig eth0 up &
dhclient &
startx &
exit 0
为了使 rc.local 开机运行脚本,不要忘了给它加上可执行权限
在没有正确的配置 X 使用 Framebuffer进行绘制时,使用 startx 开启图形界面时可能出现以下错误