6 Linux 注意事项

6.1 概述

本节包含与 Xillinux 相关的特定 Linux 主题。

关于 Xillybus 和 Linux 的更广泛视角,请参阅以下文档:

6.2 编译 Linux 内核

由于其体积较大,完整的 Linux 内核源码未包含在 Xillinux 发行版中,但可通过以下命令从 Github 下载:

$ git clone https://github.com/xillybus/xillinux-kernel.git

要精确复现 Xillinux-2.0 所使用的内核,请检出 “xillinux-2.0a” 标签。通过类似以下形式告知内核构建环境所需的交叉编译 器:

$ export CROSS_COMPILE=/path/to/crosscompiler/arm-xilinx-linux-gnueabi-

然后获取用于编译 Xillinux-2.0 内核的 .config 文件:

$ make ARCH=arm xillinux_defconfig

接着运行内核编译:

$ make ARCH=arm -j 8 uImage modules LOADADDR=0x8000

要构建设备树二进制文件(Device Tree Blobs),在如上所述设置好交叉编译器和 .config 文件后,可使用以下命令:

$ make ARCH=arm dtbs
[ ... ]
  DTC arch/arm/boot/dts/xillinux-microzed.dtb
  DTC arch/arm/boot/dts/xillinux-zedboard.dtb
  DTC arch/arm/boot/dts/xillinux-zybo.dtb
  DTC arch/arm/boot/dts/xillinux-zturn-lite.dtb

DTB 文件位于 arch/arm/boot/dts/ 中,正如命令输出所示。

6.3 编译内核模块

Xillinux 发行版附带运行中内核的编译头文件。这不足以执行内核本身的编译,但允许直接在平台上编译内核模块。

编译树外内核模块的标准方法是使用 Makefile,该 Makefile 在设置环境变量后调用内核自身的构建环境,以执行特定模块的 编译。

对于由单个源文件 example.c 构成的内核模块,本地编译(由 Zynq 处理器自身执行) 的最小 Makefile 如下:

ifneq ($(KERNELRELEASE),)
obj-m      := example.o
else
TARGET := $(shell uname -r)
PWD := $(shell pwd)
KDIR := /lib/modules/$(TARGET)/build

default:
      @echo $(TARGET) > module.target
      $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif

注意模块名称 “example” 仅在 “obj-m” 行中出现。这是不同 Makefile 之间唯一不同之处。

使用此 Makefile 通常会产生如下编译会话(在开发板本身上运行;这不是交叉编译):

# make
make -C /lib/modules/4.4.30-xillinux-2.0/build SUBDIRS=/root/example modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.30-xillinux-2.0'
 CC [M] /root/example/example.o
 Building modules, stage 2.
 MODPOST 1 modules
 CC     /root/example/example.mod.o
 LD [M] /root/example/example.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.4.30-xillinux-2.0'

6.4 音频支持

6.4.1 概述

Zedboard 和 Zybo 开发板分别通过 Analog Devices 的 ADAU1761 和 SSM2603 芯片组支持音频录制和播放。这些芯片仅连接到 Zynq 器 件的逻辑结构(PL)引脚。

除了其明显的功能外,音频支持套件还演示了如何使用 Xillybus IP 核传输数据,以及如何通过 SMBus / I2C 对芯片进行编程。

Xillinux 通过将专用的 Xillybus 数据流与当今 Linux 上最常用的音频工具包 Pulseaudio 对接,原生支持音频。因此,几乎所有需要声卡的 应用程序都会正确地将开发板的音频芯片用作系统默认输入和输出。

也可以关闭 Pulseaudio 守护进程,直接使用 Xillybus 数据流(/dev/xillybus_audio)。这提供了仅打开设备文件的更简单编 程接口,但代价是失去其他应用程序的原生功能。

与 Linux 声卡的常见方法不同,音频接口没有专用的内核驱动程序(例如 ALSA),因为 Xillybus 主机驱动程序已经处理了 数据传输。这并无大碍,即使是对期望使用 /dev/dsp 的程序也是如此,因为 Pulseaudio 能够通过 “padsp” 工具模拟该接口。

6.4.2 使用细节

默认情况下,音频播放输出到耳机插孔(黑色)。在 Zedboard 上,同一输出也会送到 Line Out(绿色)。录音仅使用麦克 风输入(粉色),但可以更改,如下所述。

6.4.3 相关启动脚本

在 Zedboard 和 Zybo 上设置音频有两个任务:对音频芯片进行编程和启动 Pulseaudio 守护进程。

对于第一个任务,/etc/systemd/system/ 中有两个 systemd 单元文件:

  • xillinux_sound.service:启动时执行 /usr/local/bin/xillinux-sound。

  • xillinux_sound.path:指示 systemd 等待 /dev/xillybus_smb 出现,一旦出现则启动上述服务。注意,这不是基于 udev,而是基于 inotify 监视 /dev。

/usr/local/bin/xillinux-sound 识别其运行的开发板,并运行相应的脚本 /usr/local/bin/zybo_sound_setup.pl 或 /usr/local/bin/zedboard_sound_setup.pl。

Pulseaudio 守护进程在用户首次登录系统时启动,这通过位于 /etc/systemd/user/ 的用户服务单元文件 xillinux_pulseaudio.service 实 现。

由于 Xillinux 在串行控制台和屏幕控制台上都自动登录 root 用户,Pulseaudio 在系统启动完成后不久便会启动。

在多用户计算机上以 root 身份运行 Pulseaudio 并不被推荐,但由于 Xillinux 默认以 root 用户运行,这是问题最小的选 择。

如果需要直接访问 /dev/xillybus_audio,则应禁用该服务,例如:

# systemctl --global disable xillinux_pulseaudio
Removed symlink /etc/systemd/user/default.target.wants/
xillinux_pulseaudio.service.

zybo_sound_setup.pl 和 zedboard_sound_setup.pl 是 Perl 脚本,用于设置音频芯片寄存器以确保正常运行。即使不熟悉 Perl 的程序员 也能较容易理解。该脚本使用 /dev/xillybus_smbus 设备文件在芯片的 I2C 总线上发起事务。

可以编辑 zedboard_sound_setup.pl 以实现音频芯片的不同设置。特别是,如果需要将 Line In 输入作为录音源,则应将以下 行:

write_i2c(0x400a, 0x0b, 0x08);
write_i2c(0x400c, 0x0b, 0x08);

替换为:

write_i2c(0x400a, 0x01, 0x05);
write_i2c(0x400c, 0x01, 0x05);

类似地,可以编辑 zybo_sound_setup.pl,将:

write_i2c(0x04, 0x14);

替换为:

write_i2c(0x04, 0x10);

以使用 Line In 进行录音。

6.4.4 直接访问 /dev/xillybus_audio

可以直接写入 /dev/xillybus_audio 进行播放,或从中读取进行录音。采样格式为每个音频采样 32 位,分为两个小端格式的 16 位有符号整数。最高有效字对应左声道。

采样率固定为 48000 Hz。

如果直接写入 /dev/xillybus_audio,与此采样率匹配的 Windows WAV 文件很可能正常播放(头部也会播放约 1 毫秒),例 如使用:

# cat song.wav > /dev/xillybus_audio

如果响应为:

-bash: /dev/xillybus_audio: Device or resource busy

则可能是另一个进程已打开该设备文件进行写入,可能是 Pulseaudio 守护进程。一个进程打开设备文件进行读取,另一个进 程打开进行写入,是没有任何问题的。

6.4.5 Pulseaudio 细节

Pulseaudio 通过两个专用的 Pulseaudio 模块(module-file-sink 和 module-file-source)与 /dev/xillybus_audio 设备文件交互。其源码可 在 Xillinux 文件系统的 /usr/src/xillinux/pulseaudio/ 中找到。

这些模块是对标准 Pulseaudio 模块(module-pipe-sink 和 module-pipe-source,用于将 UNIX 管道用作数据接收端和源)的 轻微修改。

Pulseaudio 启动时,通过 /etc/pulse/default.pa 中的以下两行自动加载这些模块:

load-module module-file-sink file=/dev/xillybus_audio rate=48000
load-module module-file-source file=/dev/xillybus_audio rate=48000

由于没有其他替代方案,这些模块会自动被选为系统的音频接口。

6.5 OLED 工具(仅限 Zedboard)

默认情况下,Xillinux 在启动期间启动一个活动指示器工具,显示近似的 CPU 使用率百分比以及 SD 闪存磁盘的 I/O 速率指 示。

CPU 百分比基于 /proc/stat,其中所有未处于空闲状态的时间均视为已用 CPU 时间。

对 SDIO 流量的估算基于发送到相应驱动程序的中断速率。对于该资源的完全利用率没有已知数值。相反,根据先前的测 量,该工具将看似最大的中断速率显示为 100%。

为了在开发板的 OLED 上显示图形输出,位图被发送到 /dev/zed_oled,该设备由 Digilent 的驱动程序创建。值得一提的 是,该驱动程序通过位操作机制向 OLED 设备发送 SPI 数据,在软件中翻转时钟和数据。因此,以这种方式每秒发送 512 字节数次会消耗少 量 CPU,但对整体系统性能的影响极小。

要更改此工具的参数,请编辑 /usr/local/bin/start_zedboard_oled,其核心命令如下:

/usr/local/bin/zedboard_oled /proc/irq/$irqnum/spurious 4 800

应用程序 zedboard_oled 接受三个参数:

  • 用于监视 SDIO 相关中断的 /proc 文件。$irqnum 是 mmc0 设备的中断号。

  • OLED 显示更新的速率,单位为次/秒。

  • 被视为 SDIO 中断速率 100% 的值,单位为中断/秒。当前数值是通过反复试验得出的。

要阻止此工具在启动时启动:

# systemctl disable zedboard_oled.path
Removed symlink /etc/systemd/system/paths.target.wants/zedboard_oled.path.

6.6 其他注意事项

  • 尽管自内核 3.12 以来 Linux GPIO 驱动程序有所变更,Xillinux-2.0 仍使用了与 Xillinux-1.3 相同的 GPIO 驱动程序,保留了 Xillinux-1.3 的行为和编号方式。

    要使用新的 GPIO 驱动程序,请将设备树条目中 compatible = “xlnx,ps7-gpio-1.00.a” 改为 “xlnx,zynq-gpio-1.0”。

  • Linux 内核以 1 位宽总线访问 Quad SPI 闪存,尽管驱动程序支持四比特接口。可以通过更改相应的设备树条目来启用四比特接口。这不 是默认设置,是为了允许同一设备树在内核 3.12(即 Xillinux-1.3)上使用。