65.9K
CodeProject 正在变化。 阅读更多。
Home

在 MicroZed 上运行 Mono(使用 Yocto)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2014 年 11 月 11 日

CPOL

11分钟阅读

viewsIcon

25426

演示如何使用Yocto项目在MicroZed开发板上启动和运行带有Mono的自定义Linux操作系统。

引言

本文是一个教程,描述了如何在MicroZed开发板上启动和运行自定义Linux基线和Mono(一个跨平台的.NET运行时环境)。它是更大文章的一部分,该文章解释了如何使用Yocto项目在多个硬件配置中建立自定义Linux基线。本教程的结果是我们的MicroZed开发板将设置为运行C#应用程序和库。这些应用程序和库可以使用高级集成开发环境(IDE)如Visual Studio、SharpDevelop或Xamarin Studio进行开发。这使得对嵌入式环境经验有限的软件开发人员能够为嵌入式物联网(IoT)设备编写软件。

安装

本文不涵盖MicroZed的基本设置(电源连接、跳线设置、串口输出等),因为假设希望使用本教程的板卡所有者对随板卡提供的快速入门指南或参考手册中的这些连接有基本了解。本文的重点是使用Yocto构建针对开发板的所需环境。

本教程使用以下软件和硬件组件:

我们将使用的主要Yocto项目工具是Poky构建系统。为了使用此工具,我们需要一个Linux开发环境。大多数主流Linux发行版都受支持。我使用的是Mint 17 64位。Yocto项目网站还有一个“构建设备”,其中包含一个VMWare虚拟Linux系统镜像,已全部设置好可供使用。如果在您自己的Linux环境中使用Poky,请务必安装所需的依赖项(有关更多信息,请参阅Yocto项目网站上的快速入门或参考手册 www.yoctoproject.org)。我必须安装的软件包包括:g++、texinfo、libsdl1.2-dev、texi2html、cvs、subversion、bison、flex和mono-complete(用于构建Mono)。

我还建议您阅读Yocto项目网站上的一些快速入门文档。我将在本文中概述为MicroZed创建启动镜像和文件的步骤,但可以通过Yocto的在线文档获得对Yocto功能和特性的更深入理解。

使用代码

在Linux开发系统端应在终端运行的命令以 $ 提示符显示

$ 

在开发板上应运行的命令以 # 提示符显示

#

文件修改将使用“...”表示所引用部分之前和之后的文件文本。这将允许我们显示文件中需要更改的部分,而无需显示整个文件内容。

...

Text in the file

...

教程

为Raspberry Pi poky构建环境创建一个文件夹

$ mkdir ~/microzed

将git Yocto项目核心克隆到poky工作目录中

$ git clone -b daisy git://git.yoctoproject.org/poky.git ~/microzed

我们现在需要引入与我们的处理器或板相关的板级支持包。meta-xilinx板级支持包适用于MicroZed板。此元数据层由Xilinx维护,位于Yocto项目网站上。如果您无法使用Yocto网站找到目标板的BSP,请尝试搜索“yocto <板卡或处理器> bsp”,您可能会找到社区维护的BSP。

将meta-xilinx板级支持包克隆到poky工作目录中。注意:在引入板级支持包时,请务必阅读与该包或在线存储库“关于”部分关联的README文件。有时它们有额外的步骤必须执行才能使用BSP。

$ git clone -b daisy git://git.yoctoproject.org/meta-xilinx ~/microzed/meta-xilinx

将meta-mono元数据层克隆到poky工作目录中

$ git clone -b daisy git://git.yoctoproject.org/meta-mono ~/microzed/meta-mono

来源构建环境脚本以创建配置文件

$ cd ~/microzed
$ source oe-init-build-env

将meta-xilinx板级支持包层和Mono元数据层添加到构建环境中。通过打开~/microzed/build/conf/bblayers.conf文件,并在meta-yocto-bsp之后将这些层添加到BBLAYERS变量中。完成后,该文件应如下所示:

...
  /home/<username>/microzed/meta-yocto-bsp \
  /home/<username>/microzed/meta-xilinx \
  /home/<username>/microzed/meta-mono \
  "
...

现在将MACHINE变量更改为MicroZed板。这告诉构建环境在构建Linux环境时以哪个板为目标。为此,编辑~/microzed/build/conf/local.conf文件。向下扫描文件直到找到以下部分:

...
#MACHINE ?= "edgerouter"
#
# This sets the default machine to be qemux86 if no other machine is selected:
MACHINE ??= "qemux86"
...

在默认值上方添加MicroZed板参考作为MACHINE,以便文件内容如下:

...
#MACHINE ?= "edgerouter"
MACHINE ?= "zedboard-zynq7"
#
# This sets the default machine to be qemux86 if no other machine is selected:
MACHINE ??= "qemux86"
...

这将构建环境设置为以ZedBoard为目标。如果您不知道机器名称是什么,可以查看BSP文件夹 (meta-xilinx) 的子文件夹:conf/machine (~/microzed/meta-xilinx/conf/machine)。此文件夹中 .conf 文件的名称都是板级支持包可以作为目标的所有机器的名称。另请注意,默认机器是qemux86。QEMU是一个开源机器模拟器。您可以使用此模拟器在实际针对特定板之前试用自定义构建的Linux发行版。

请注意,机器的实际名称是“zedboard-zynq7”。Zed板和MicroZed板之间似乎没有单独的机器名称。如果您想要添加不同的特定硬件驱动程序,您可能需要自己开发一个自定义配置文件。出于我们的目的,这个默认机器配置将起作用。

您可能希望在此阶段构建一个最小镜像,以确定您的构建环境是否设置正确。您可以通过运行“bitbake core-image-minimal”来完成此操作。我们将跳过此步骤,继续构建包含Mono的最小镜像。

有许多方法可以混合和匹配软件包和配方。Mono元数据层已经为我们提供了一些配方,可以将Mono添加到我们想要创建的任何镜像中;但是,在这里我们将创建自己的镜像配方,其中包含带有Mono运行时的最小Linux镜像。这意味着Mono的GUI元素(依赖于libgdiplus的类)将无法工作,因为基本的最小镜像不包含GDI。由于许多物联网应用程序可能不包含图形界面,我们认为这是显示在板上运行C#的最小要求的最佳方法。

我们需要做的第一件事是创建一个包含文件,告诉构建环境我们需要包含什么。您可以通过运行以下命令来完成此操作:

$ (cat << EOF
> IMAGE_INSTALL += "mono mono-helloworld"
> EOF
> ) > ~/microzed/meta-mono/recipes-mono/images/core-image-minimal-mono.inc

此命令在meta-mono层中生成文件。您也可以为此创建自己的层。如果您将此包含文件与~/microzed/meta-mono/recipes-mono/images/core-image-mono.inc文件进行比较,您会注意到唯一的区别是省略了libgdiplus依赖项。

现在让我们创建实际的bitbake配方文件。您可以通过运行以下命令来完成:

$ (cat << EOF
> require recipes-core/images/core-image-minimal.bb
> require core-image-minimal-mono.inc
> EOF
> ) > ~/microzed/meta-mono/recipes-mono/images/core-image-minimal-mono.bb

此命令生成bitbake配方文件。这个配方相当简单。第一行告诉构建环境包含用于制作core-image-minimal镜像的配方。第二行告诉环境将Mono文件添加到镜像中。请注意,上面创建的两个文件都不与任何特定硬件绑定。bitbake构建过程的设计使得您可以在非常不同的硬件目标上重用这些配方。

我们现在已经有了镜像配方,准备开始“烘焙”。输入以下命令来构建镜像(确保您在构建目录中):

$ bitbake core-image-minimal-mono

这个过程可能需要很长时间,具体取决于您的环境和互联网连接。它将首先解析所有配方,并确定需要从各个仓库下载哪些源代码。请注意,即使我们只在配方文件中包含了两个配方,这两个配方也代表了大量依赖配方的层次结构。解析过程会遍历依赖关系,并确定所有需要下载的文件。它会下载源代码并将其本地缓存。这样做的好处是,后续可能需要源代码的构建无需访问互联网即可获取。缺点是,根据您尝试构建的配方,您可能会下载和存储大量文件。在完成此构建过程后,我们的~/microzed文件夹增长到21GB。这代表了即使是最小构建也所需的存储量。

上图显示了创建自定义Linux镜像时终端上应显示内容的示例。

当进程成功完成时,您可以在~/microzed/build/tmp/deploy/images/zedboard-zynq7目录中找到所需的启动文件。此文件夹中的文件比启动板所需的要多得多。我们将需要以下文件:

  1. u-boot.elf
  2. uImage
  3. uImage-zedboard-zynq7.dtb
  4. core-image-minimal-mono-zedboard-zynq7.tar.gz
  5. modules-zedboard-zynq7.tgz

我们仍然需要使用Xilinx工具生成第一阶段引导加载程序。一旦生成了该elf文件,我们将其与u-boot.elf和FPGA逻辑比特流结合成一个BOOT.BIN文件。Zynq IC会查找此文件来启动系统。它将u-boot加载到系统中并运行它。u-boot是一个引导加载程序,可以读取Linux内核镜像(uImage)并以特定参数启动Linux环境。镜像文件(tar.gz)和模块文件包含Linux基本文件系统和需要安装到其中的附加模块。

接下来我们需要生成BOOT.BIN文件。有关如何操作的说明可以在Xilinx Vivado文档中提供的各种指南中找到。 Adam Taylor 也有许多关于此的优秀博客文章。一个快速的运行过程如下:

  1. 使用Vivado创建一个硬件设计
  2. 将硬件设计导出到Xilinx SDK
  3. 在SDK中,使用导出的硬件设计创建一个板级支持包项目
  4. 使用第一阶段引导加载程序模板向SDK工作区添加一个项目
  5. 编译项目(您现在应该从工具中获得一个比特流和一个第一阶段引导加载程序elf文件)
  6. 运行“创建Zynq启动镜像”工具,并将第一阶段引导加载程序elf文件添加为引导加载程序
  7. 将剩余文件添加到镜像中(Vivado生成的比特流、u-boot.elf、uImage-zedboard-zynq7.dtb作为devicetree.dtb,以及Yocto构建输出中的uImage作为uImage.bin)

此工具的输出应该是一个BOOT.BIN文件。将其复制到~/microzed/build/tmp/deploy/images/zedboard-zynq7目录中。

接下来我们需要生成包含u-boot设置Linux环境的特定参数的文件。该文件可以使用以下命令创建:

$ (cat << 'EOF'
> kernel_image=uImage
> devicetree_image=uImage.dtb
> bootargs=console=ttyPS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait earlyprintk
> uenvcmd=echo Copying Linux from SD to RAM... && fatload mmc 0 0x3000000 ${kernel_image} && fatload mmc 0 0x2A00000 ${devicetree_image} && bootm 0x3000000 - 0x2A00000
> EOF
> ) > ~/microzed/build/tmp/deploy/images/zedboard-zynq7/uEnv.txt

如果您熟悉u-boot,其中一些参数可能看起来很熟悉。这个文件中可以包含许多不同的内核参数。上面这个是在meta-xilinx元数据层提供的BOOT.sdcard文档中找到的。

我们现在拥有启动系统所需的所有文件。让我们创建可启动的SD卡并将其插入系统。本教程中的所有开发板都使用双分区SD卡启动。第一个分区包含一个FAT文件系统,其中包含内核和一些启动文件。第二个分区是一个ext3分区,其中包含文件系统。我不会讨论SD卡分区,因为网上有多个关于此的教程,并且它通常取决于您卡的尺寸和参数。

如果您已有分区卡,我建议使用以下命令重新格式化两个分区,以便从一个干净的文件系统开始(FAT部分需要)。将“mmcblk0p1”和“mmcblk0p2”分区替换为SD卡上的分区(可能是sda1和sda2等)。请务必选择正确的分区(您不希望格式化错误的驱动器)。

$ umount /dev/mmcblk0p1
$ umount /dev/mmcblk0p2
$ sudo mkfs.vfat -F 32 -n "boot" /dev/mmcblk0p1
$ sudo mkfs.ext3 -L "root" /dev/mmcblk0p2

此时在我的Mint系统上,卡以/media/mint/boot和/media/mint/root挂载了boot和root分区。(mint是我的用户名。)您可能需要根据您的Linux环境手动挂载分区。以下命令将使用我挂载的文件夹。请务必调整命令以符合您系统的挂载文件夹。

现在让我们将所需文件复制到SD卡。

$ cp ~/microzed/build/tmp/deploy/images/zedboard-zynq7/BOOT.BIN /media/mint/boot/BOOT.BIN
$ cp ~/microzed/build/tmp/deploy/images/zedboard-zynq7/uImage /media/mint/boot/uImage
$ cp ~/microzed/build/tmp/deploy/images/zedboard-zynq7/uImage-zedboard-zynq7.dtb /media/mint/boot/uImage.dtb
$ cp ~/microzed/build/tmp/deploy/images/zedboard-zynq7/uEnv.txt /media/mint/boot/uEnv.txt

这涵盖了启动分区;现在让我们将自定义Linux文件系统复制到第二个分区。

$ sudo tar xzpf ~/microzed/build/tmp/deploy/images/zedboard-zynq7/core-image-minimal-mono-zedboard-zynq7.tar.gz -C /media/mint/root
$ sudo tar xf ~/microzed/build/tmp/deploy/images/zedboard-zynq7/modules-zedboard-zynq7.tgz -C /media/mint/root

我们现在已经设置好可以从SD卡启动了。弹出卡并插入MicroZed开发板。如果SD卡启动到类似以下的登录界面:

Poky (Yocto Project Reference Distro) 1.6.2 zedboard-zynq7 /dev/ttyPS0

zedboard-zynq7 login:

使用“root”作为用户名登录,您应该可以访问shell。现在输入以下命令,以确定Mono是否设置正确:

# mono --version

它应该显示类似以下内容:

Mono JIT compiler version 3.4.0 (tarball Sat Nov  8 10:52:14 MST 2014)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       normal
        Notifications: epoll
        Architecture:  armel,vfp
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

由于我们在镜像中包含了mono-helloworld配方,您应该能够运行以下命令:

# mono /usr/lib/helloworld/helloworld.exe

如果控制台打印出“HelloWorld”,那么您就成功地在开发板上运行了一个.NET应用程序。

历史

2014年11月11日 - 初次提交

© . All rights reserved.