Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XILINX/Zynq 7z010/7z020 相关 #1006

Open
cisen opened this issue Nov 28, 2020 · 6 comments
Open

XILINX/Zynq 7z010/7z020 相关 #1006

cisen opened this issue Nov 28, 2020 · 6 comments
Labels

Comments

@cisen
Copy link
Owner

cisen commented Nov 28, 2020

总结

捕获

捕获616

捕获98498

捕获555115

1111

2222

vivado

流程

创建工程

  • 选择完文件夹和工程名后,project type选择RTL Project和勾选上do not specify sources at this time
  • 默认板子选择xc7z020clg400-2

使用IP Integrator创建Processor System

  • 进入工程后,选择左边的create block design,输入design name为system,点ok
  • 在Diagram面板右键Add IP,弹窗搜索ZYNQ,然后双击添加
  • 双击IP进入IP设置,DDR :MT41K256M16 RE-125, 32Bit
  • Peripheral I/O Pins,UART 选择uart1 24,25
  • MIO Configuaration,bank 1 I/O voltage选择LVCMOS 3.3V
  • PS-PL,将AXI GP0的interface取消勾选。再将General下面的Enable Clock Rests下面的勾去掉
  • Clock Configuration,PL Fabric clocks下面的CLK取消勾选,点击ok保存
  • 点击diagram下面的:Run Block Automation,使用默认点击ok
  • 点击diagram菜单的勾(validate design)

生成顶层HDL

  • 在source》design sources》system右键generate Output products,选择默认,然后generate
  • 在source》design sources》system右键Create HDL Wrapper,默认,点ok

生成Bitstream,并导出到SDK

  • 选择右上角的File》export》export Hardware,不要勾选上include bitstream,点击ok
  • 点击File》Launch SDK,默认,点击ok

在SDK中创建应用工程

  • 在eclips里面选择File》create project》输入标题》next,选择empty application》finish
  • 在hello》src右键》new》source file》文件名输入main.c
#include "stdio.h"

int main(){
	printf("hello, world\n");
	return 0;
}
  • 在中间的SDK Terminal的右边按下+,然后选中对应的串口和波特率
  • 在c项目hello右键,选中Run as》1 Launch on Hardware(System debugger)

I/O Port 管脚分配

  • 注意时钟要分配到MRCC/SRCC类型的脚上
  • 分配的结果可以看:package图,也可以在图中找到对可分配的管脚
@cisen cisen added the FPGA label Nov 28, 2020
@cisen cisen changed the title Zynq 7z010/7z020 相关 XILINX/Zynq 7z010/7z020 相关 Dec 6, 2020
@cisen
Copy link
Owner Author

cisen commented Dec 6, 2020

zynq[1] 矿板helloworld

最近矿难,某宝某鱼上都出现了大量矿机控制板。。。ASIC负责挖矿,控制板负责联网、监视、控制之类。控制板不乏有各种水果派,像香橙派、树莓派、狗骨头之类的所谓“极客玩具”在其之列,想必国内水果派厂家活的是相当滋润。。。光靠极客教育哪有什么赚头,极客大都很穷的,像我这样看到这么便宜的“zynq开发板”,便忍不住要跟风收一波垃圾了。。。

某鱼上EBAZ4205控制板泛滥,它出自翼比特E9+矿机。它的老版控制卡EBAZ4203配置与其基本一样。
ebazE9p

下面一大坨都是计算卡,上面一小块才是控制板

板子概况

ebaz4205-3

-- | --
主控 | XC7Z010CLG400-1
内存 | 256MB DDR3,EM6GD16EWKG或者MT41K128M16
nand | 128MB SLC
以太网 | 百兆网卡,IP101GA
供电 | 5V也行
其他 | TF卡,UART1,2个风扇口,14针jtag,3个20pin IO口

开发工程

SOC启动配置

ZYNQ系列的SOC集成了双核ARM Cortex-A9和FPGA。整个SOC分为PS(processing system)和PL(programmable logic)两部分。PS包括处理器、片上AMBA总线、存储控制器、部分外设以及固定的IO口;PL就是FPGA。ZYNQ 7010处理器主频可以到约600MHz,FPGA有约28K个LE。

zynqbd

ZYNQ的PS部分可以抛开PL部分而独立运行,因为PS的外设都默认绑定了一些IO口(MIO),内存控制器之类的IO口还是不可更改的,这时候就可以像开发其他ARM SOC那样去玩ZYNQ。MIO是有限的,一些外设端口冲突的话可以通过EMIO绕道PL将其引出,这时候就需要管PL部分了。

ZYNQ的启动分为三步:

BOOT ROM,根据引脚配置选择从哪里启动,如QSPI、nand/nor flash、SD卡等。将FSBL(first stage bootloader)加载到片上内存里。7010的片上内存有256k。
FSBL,初始化更多的MIO口,初始化DDR,还可以初始化PL部分,然后将应用程序搬到DDR中。初始化部分由vivado直接生成,即那个上万行的ps7_init.c。FSBL可以直接用Xilinx SDK的例子工程,相当于这些工作都可以点点鼠标就完成了。
应用程序。可以直接是用户的应用程序,也可以是又一个loader,比如uboot之类的,剩下的事情就由程序员自己做决定了。
应当指出,FSBL相当于是uboot SPL的地位。在Xilinx uboot工程中,那个上万行的初始化c程序就编译进SPL中去了,所以如果用SDK的FSBL就不需要uboot的SPL了。

这块板子的R2577和R2584电阻用于配置启动设备。把R2584焊到R2577上,将原来nand启动改为SD卡启动。

ebaz4205-2

Vivado操作流程

利用Xilinx那套笨重的开发环境,helloworld工程完全可以用鼠标操作出来,一行代码都不用写。。

首先新建个工程
一直next到选择芯片。选xc7z010clg400-1
vivado1

接下来就顺着左边栏Flow Navigator进行操作。
vivado2

Create Board Design

点加号添加ZYNQ7 Processing System:
vivado3

双击出来的zynq7 processing system蓝框框,配置PS系统:

添加nand控制器,默认就行了:
vivado4

添加MIO设置。勾上ENET0、SD0、UART1。注意引脚配置:
vivado5

设置外设时钟。把网口改成百兆的:
vivado7

设置DDR。幸好我们的MT41K128M16有默认参数配置:
vivado6

因为板子的网口通过EMIO引出,所以我们需要一个个手动分配引脚。但是这个IP是GMII千兆网口,TX RX有8位,而百兆网卡用的MII接口TX RX只有4位,必须显式地加两个concat模块来将8位转为4位,否则多余的引脚引出了但是不分配IO口,最后生成bitstream时候会报错。
vivado8

vivado
vivado
将GMII的TX、RX引到各自的concat模块处,将GMII其他引脚以及MDIO引出:右键点击Make External
vivado10

vivado
vivado
将FCLK_CLK0跟M_AXI_GP0_ACLK连起来,最后点击上方栏的Run Block Automation完成剩下的工作。
vivado9

vivado
vivado
完成后的效果:
vivado11

vivado
vivado

左边栏Generate Block Design

先Generate Block Design,然后右键Source框下面的bd文件,Create HDL Wrapper:
vivado12

vivado
vivado

左边栏Run Synthesis

先综合一次,然后打开Open Synthesized Design->Constraint Wizard,分配引脚。这时需要新建一个constraint文件。

将网口的引脚都设置为LVCMOS33电平,然后逐个分配引脚。。。
vivado13

vivado
vivado
设置完成后Ctrl-S保存,约束文件生成如下:

set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_CLK_0]
...
set_property PACKAGE_PIN U14 [get_ports ENET0_GMII_RX_CLK_0]
set_property PACKAGE_PIN U15 [get_ports ENET0_GMII_TX_CLK_0]
set_property PACKAGE_PIN W19 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property PACKAGE_PIN W18 [get_ports {enet0_gmii_txd[0]}]
set_property PACKAGE_PIN Y18 [get_ports {enet0_gmii_txd[1]}]
set_property PACKAGE_PIN V18 [get_ports {enet0_gmii_txd[2]}]
set_property PACKAGE_PIN Y19 [get_ports {enet0_gmii_txd[3]}]
set_property PACKAGE_PIN W16 [get_ports ENET0_GMII_RX_DV_0]
set_property PACKAGE_PIN W15 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property PACKAGE_PIN Y14 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property PACKAGE_PIN Y16 [get_ports {enet0_gmii_rxd[0]}]
set_property PACKAGE_PIN V16 [get_ports {enet0_gmii_rxd[1]}]
set_property PACKAGE_PIN V17 [get_ports {enet0_gmii_rxd[2]}]
set_property PACKAGE_PIN Y17 [get_ports {enet0_gmii_rxd[3]}]

然后再综合一次。。。

左边栏Run Implementation 和 Generate Bitstream

要跑一段时间。。。

输出设计

File->Export->Export Hardware

记得勾上Include Bitstream。

进入SDK

File->Launch SDK

SDK操作流程

首先需要新建FSBL。

File->New->Application Project,Next到Templates,选Zynq FSBL:
sdk1

sdk
sdk
然后它会自动开始编译。。。

然后才新建helloworld。。

File->New->Application Project,Next到Templates,选Hello World。它也会自动开始编译,不出意外的话就完事了。

最后生成启动文件BOOT.bin

左边栏右键helloworld工程,Create Boot Image。可以看到这个启动文件包括了三部分:
sdk2

fsbl
bitstream
应用程序
sdk
sdk

点亮板子

将一张SD卡格式化为fat文件系统,将bootimage/BOOT.bin丢进去,插上电就能启动了。
sdk3

sdk
sdk

测试网口

SDK里面新建lwIP Echo Server工程,等它编译完,生成BOOT.bin,拷到SD卡里。插好网线,在终端中telnet它的7号端口,输入一行,回车,然后它就将你输入的东西返回来了。。。

telnet
ebaz4205-1

@cisen
Copy link
Owner Author

cisen commented Dec 6, 2020

zynq[2] Linux from scratch

  • https://hhuysqt.github.io/zynq2/
    Xilinx有个工具叫PetaLinux,它可以一键生成uboot、Linux、根文件系统。但是按照惯例我们还是自己敲命令一个个来吧。

Xilinx有个wiki讲述如何一步步做Linux from scratch。有些步骤是多余的,比如编译设备树的工具链。鉴于我们的EBAZ4205是块野生的板子,需要稍微做一些配置。

安装vivado、SDK时候顺便安装了arm-linux-gnueabihf-以及其他Xilinx自家的工具链,不妨将其export到PATH:

gcc

export PATH=/某某某/SDK/2017.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/:$PATH

bootgen etc.

export PATH=/某某某/SDK/2017.4/bin:$PATH
所有工作开始之前,还要export ARCH和CROSS_COMPILE两个环境变量:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
uboot
uboot只需要极少量的配置,就基本上works out of the box了。现在我们先用tftp来启动内核。各部分的地址如下:

  文件名 启动地址
设备树 zynq-zc702.dtb 0
内核 uImage 0x8000
文件系统 uramdisk.image.gz 0x01000000

https://github.com/Xilinx/u-boot-xlnx上下载Xilinx家的uboot,当然也可以选择去下载release版本的。

改改配置
arch/arm/dts/zynq-zc702.dts的memory节点,内存大小改为256MB

@@ -21,7 +21,7 @@

 memory@0 {
     device_type = "memory";
  •    reg = <0x0 0x40000000>;
    
  •    reg = <0x0 0x10000000>;
    

    };

    chosen {
    直接用zynq_zc702_defconfig:

make zynq_zc702_defconfig
关闭CONFIG_ENV_IS_IN_SPI_FLASH,不然启动时候会卡死在SPI flash初始化部分。这时候就用默认的环境变量。
开启CONFIG_NAND、CONFIG_NAND_ZYNQ,以开启nand命令。
定制环境变量,改include/configs/zynq-common.h,主要是来配置启动参数。

tftp之前得显式地设置serverip
要tftp内核、设备树、根文件系统
set serverip xxx.xxx.xxx.xxx
dhcp
tftpboot 0 zynq-zc702.dtb
tftpboot 8000 uImage
tftpboot 1000000 uramdisk.image.gz
bootm 8000 1000000 0
然后make,生成了u-boot可执行文件。

生成BOOT.bin
我们写一个boot.bif,引用之前建的helloworld工程中的FSBL和bitstream:

the_ROM_image:
{
[bootloader]/某某某/fsbl.elf
/某某某/ebaz4205_wrapper.bit
/某某某/u-boot.elf
}
利用vivado安装的工具bootgen,通过上述配置文件来生成BOOT.bin。u-boot需要重命名为u-boot.elf,不然bootgen不认为它是ELF文件,就当它是bin文件来处理了。。。

mv u-boot u-boot.elf
bootgen -image boot.bif -o i BOOT.bin -w
Linux内核
内核很大程度上也是work out of the box了,改改设备树就好。

https://github.com/Xilinx/linux-xlnx上下载Xilinx家的内核。目前版本是4.19.0,还是挺新的。

设备树
首先还是得将内存大小改对:

    memory@0 {
            device_type = "memory";
  •           reg = <0x0 0x40000000>;
    
  •           reg = <0x0 0x10000000>;
      };
    

因为我们的野生板子外设很少,必须将不用的外设disabled掉,不然引脚配置会打架。

&can0 {

  •   status = "okay";
    
  •   status = "disabled";
    

...

&i2c0 {

  •   status = "okay";
    
  •   status = "disabled";
    

&qspi {
u-boot,dm-pre-reloc;

  •   status = "okay";
    
  •   status = "disabled";
    

&usb0 {

  •   status = "okay";
    
  •   status = "disabled";
    

串口的引脚要改对:

@@ -368,12 +382,12 @@
};

     conf-rx {
  •        pins = "MIO49";
    
  •        pins = "MIO25";
           bias-high-impedance;
       };
    
       conf-tx {
    
  •        pins = "MIO48";
    
  •        pins = "MIO24";
           bias-disable;
       };
    
    };
    网口通过EMIO引出,因此gem0的引脚声明应该删掉,否则会跟串口引脚打架,导致启动到一半串口没输出了。。并且ethernet_phy节点的reg参数应改为0,不然会枚举不到那个网卡:

&gem0 {
status = "okay";
phy-mode = "rgmii-id";
phy-handle = <&ethernet_phy>;

  • pinctrl-names = "default";

  • pinctrl-0 = <&pinctrl_gem0_default>;

  • phy-reset-gpio = <&gpio0 11 0>;

  • phy-reset-active-low;

  • ethernet_phy: ethernet-phy@7 {

  •    reg = <7>;
    
  • ethernet_phy: ethernet-phy@0 {
  •    reg = <0>;
       device_type = "ethernet-phy";
    
    };
    };
    SDIO接口也在fsbl初始化完成了,所以它的引脚声明也要删掉:

&sdhci0 {
u-boot,dm-pre-reloc;
status = "okay";

  • pinctrl-names = "default";
  • pinctrl-0 = <&pinctrl_sdhci0_default>;
    };
    为了用nand flash,需要添加nand节点。在阿莫论坛有个帖子,62楼列举了原板子启动的log,可以看到它有9个分区:

Creating 9 MTD partitions on "pl35x-nand":
0x000000000000-0x000000300000 : "nand-fsbl-uboot"
0x000000300000-0x000000800000 : "nand-linux"
0x000000800000-0x000000820000 : "nand-device-tree"
0x000000820000-0x000001220000 : "nand-rootfs"
0x000001220000-0x000002220000 : "nand-jffs2"
0x000002220000-0x000002a20000 : "nand-bitstream"
0x000002a20000-0x000006a20000 : "nand-allrootfs"
0x000006a20000-0x000007e00000 : "nand-release"
0x000007e00000-0x000008000000 : "nand-reserve"
所以我们这样设置nand0节点:

&nand0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand0_default>;
partition@0 {
label = "nand-fsbl-uboot";
reg = <0x0 0x300000>;
};
partition@1 {
label = "nand-linux";
reg = <0x300000 0x500000>;
};
partition@2 {
label = "nand-device-tree";
reg = <0x800000 0x20000>;
};
partition@3 {
label = "nand-rootfs";
reg = <0x820000 0xa00000>;
};
partition@4 {
label = "nand-jffs2";
reg = <0x1220000 0x1000000>;
};
partition@5 {
label = "nand-bitstream";
reg = <0x2220000 0x800000>;
};
partition@6 {
label = "nand-allrootfs";
reg = <0x2a20000 0x4000000>;
};
partition@7 {
label = "nand-release";
reg = <0x6a20000 0x13e0000>;
};
partition@8 {
label = "nand-reserve";
reg = <0x7e00000 0x200000>;
};
};
它的引脚配置pinctrl_nand0_default如下:

pinctrl_nand0_default: nand0-default {
    mux {
        groups = "smc0_nand8_grp";
        function = "smc0_nand";
    };

    conf {
        groups = "smc0_nand8_grp";
        bias-pull-up;
    };
};

groups的名字是在pinctrl-zynq.c第715行找到的。

由于在zynq-7000.dtsi里,nand0是smcc的子节点,所以还要使能smcc节点:

&smcc {
status = "okay";
};
为了避免pinctrl_gpio0_default跟pinctrl_nand0_default引脚打架,前者的引脚都应该删掉:

 pinctrl_gpio0_default: gpio0-default {
     mux {
         function = "gpio0";
  •        groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
    
  •             "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
    
  •             "gpio0_13_grp", "gpio0_14_grp";
    
  •        groups = "";
       };
    
       conf {
    
  •        groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
    
  •             "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
    
  •             "gpio0_13_grp", "gpio0_14_grp";
    
  •        groups = "";
           slew-rate = <0>;
           io-standard = <1>;
       };
    
       conf-pull-up {
    
  •        pins = "MIO9", "MIO10", "MIO11", "MIO12", "MIO13", "MIO14";
    
  •        pins = "";
           bias-pull-up;
       };
    
       conf-pull-none {
    
  •        pins = "MIO7", "MIO8";
    
  •        pins = "";
           bias-disable;
       };
    
    };
    其他节点该删的都要删掉,比如gpio-keys、leds、usb_phy0等。还有一些pinctrl的节点,看着碍事也不妨删掉,比如pinctrl_gem0_default等。。

编译
其实用xilinx_zynq_defconfig已经足够,不过如果想要更多的功能,比如ZRAM压缩内存之类的比较骚的设施,也可以稍微配置一下。。

记得我们uboot会将内核放在32K开始的内存地址处。然后编译设备树。

make xilinx_zynq_defconfig
make uImage UIMAGE_LOADADDR=0x8000
make dtbs
rootfs
从Build and Modify a Rootfs上下载人家编译好的busybox做的文件系统arm_ramdisk.image.gz,然后将它打包为uboot能识别的格式:

mkimage -A arm -T ramdisk -C gzip -d arm_ramdisk.image.gz uramdisk.image.gz
启动!
装好tftp server,将uImage、zynq-zc702.dtb、uramdisk.image.gz放进去。将BOOT.bin丢进格式化为fatfs的SD卡的根目录里面,然后就可以等它启动了。

Booting kernel from Legacy Image at 00008000 ...

Image Name: Linux-4.19.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4322424 Bytes = 4.1 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK

Loading init Ramdisk from Legacy Image at 01000000 ...

Image Name:
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 5309954 Bytes = 5.1 MiB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK

Flattened Device Tree blob at 00000000

Booting using the fdt blob at 0x000000
Loading Kernel Image ... OK
Loading Ramdisk to 0e5f3000, end 0eb03602 ... OK
Loading Device Tree to 0e5ec000, end 0e5f27a6 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.19.0-xilinx (hyq@ict) (gcc version 6.2.1 20161114 (Linaro GCC Snapshot 6.2-2016.11))
#19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d

....

VFS: Mounted root (ext4 filesystem) on device 1:0.
Starting rcS...
++ Mounting filesystem
mount: mounting /dev/mmcblk0p1 on /mnt failed: No such file or directory
mount: mounting /dev/mmcblk0 on /mnt failed: No such file or directory
++ Setting up mdev
++ Starting telnet daemon
++ Starting http daemon
++ Starting ftp daemon
++ Starting ssh daemon
random: sshd: uninitialized urandom read (32 bytes read)
rcS Complete
zynq>
zynq>
zynq>
zynq> uname -a
Linux (none) 4.19.0-xilinx #19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019 armv7l GNU/Linux
zynq>

@cisen
Copy link
Owner Author

cisen commented Dec 6, 2020

zynq[3] bootstrap Ubuntu

Ubuntu、Debian之类的不同的发行版,其实就是不同的rootfs。Debian系的发行版有个工具叫debootstrap,可以从源那里下载最小的根文件系统。Arch相应的工具则是packstrap。

下完根文件系统之后chroot进去进行相应的配置,为了chroot到一个ARM的rootfs,我们需要用qemu-arm-static。进去之后apt-get你想要安装的东西。配完了之后烧进sd卡,通过内核参数root=xxxx告诉内核要挂载哪个rootfs,即可启动了。

要制作一个叉叉派的镜像都是这样的套路:bootstrap一个最小系统,安装内核模块,安装必要的应用程序,然后安装不同的桌面环境,最后打包。于是就制作出各种水果派的n多镜像,像Ubuntu core、Ubuntu mate、xubuntu、lubuntu、Debian,Arch等等,应有尽有。。

然而这些大型发行版的“最小系统”都相当的大,几百兆的样子,而我们的EBAZ4205只有128M的nand flash,所以只好从sd卡启动才能维持得了生活。

准备工作
我们先在一台Ubuntu主机上安装qemu-user-static、debootstrap,然后继续。后文一些命令如果没有安装,随时apt-get一下。

准备镜像文件
我们dd一个3.7G的空白镜像,这样可以烧录进一个标明4G的SD卡。姑且叫它ubuntu1804.img吧:

dd if=/dev/zero of=ubuntu1804.img bs=1M count=3500
然后我们将它挂载为loop设备:

sudo losetup -f --show ubuntu1804.img
如果你之前没有挂过别的回环设备的话,一般它会挂在/dev/loop0。

然后我们给它分区。可以用图形界面的工具如gparted,也可以用命令行工具如parted、fdisk等。比方说我们用fdisk。

sudo fdisk /dev/loop0
用n来添加新分区。顺着它的指示走下去即可。

  文件系统 大小
启动分区 vfat 256MB就够了
文件系统 ext4 3.2G

同步这些分区。这样会在/dev/mapper/下面生成对应的节点:

sudo kpartx -av /dev/loop0
格式化它们:

sudo mkfs.vfat /dev/mapper/loop0p1
sudo mkfs.ext4 /dev/mapper/loop0p2
挂载它们:

mkdir boot rootfs
sudo mount /dev/mapper/loop0p1 boot
sudo mount /dev/mapper/loop0p2 rootfs
uboot和设备树改动
我们要修改uboot环境变量,让它从SD卡里面读取内核和设备树。不过zc702工程的默认启动设备就是sd卡,我们只需要留意sdboot这个环境变量以及各种地址就好了:

  • "kernel_load_address=0x2080000\0" \
  • "kernel_load_address=0x8000\0"
    ...
  • "devicetree_image=devicetree.dtb\0" \
  • "devicetree_load_address=0x2000000\0" \
  • "devicetree_image=zynq-zc702.dtb\0" \
  • "devicetree_load_address=0x0\0"
    ...
    "sdboot=if mmcinfo; then " \
  •    "run uenvboot; " \
       "echo Copying Linux from SD to RAM... && " \
       "load mmc 0 ${kernel_load_address} ${kernel_image} && " \
       "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \
    
  •    "load mmc 0 ${ramdisk_load_address} ${ramdisk_image} && " \
    
  •    "bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}; " \
    
  •    "bootm ${kernel_load_address} - ${devicetree_load_address}; " \
    

    "fi\0"
    我们还要修改设备树,添加启动参数,让内核挂载Ubuntu文件系统。其中rootwait这个参数表示需要等待根文件系统的挂载,不然内核启动很快,一看还没有挂上文件系统就会kernel panic了:

    chosen {

  •    bootargs = "";
    
  •    bootargs = "root=/dev/mmcblk0p2 rw rootwait";
       stdout-path = "serial0:115200n8";
    
    };
    将BOOT.bin、uImage、zynq-zc702.dtb放进启动分区。

安装最小系统
接着就可以愉快地debootstrap了。不过可惜的是,国内Ubuntu源都没有同步armhf的port,只有x86的,所以只能用官方源了。

sudo debootstrap --arch=armhf --foreign bionic ./rootfs
但是国内的Debian就同步了arm的分支,比方说清华源:

sudo debootstrap --arch=armhf --foreign stretch ./rootfs https://mirrors.tuna.tsinghua.edu.cn/debian/
等一段时间下完基本系统,然后拷贝qemu进去:

sudo cp -av /usr/bin/qemu-arm-static rootfs/usr/bin/
还需要拷贝resolv.conf,以便联网:

sudo cp /run/systemd/resolve/stub-resolv.conf rootfs/etc/resolv.conf
然后chroot进去:

sudo chroot ./rootfs
在里面进行second-stage:

chroot环境下面:

export LANG=C
/debootstrap/debootstrap --second-stage
安装完成之后,补全/etc/apt/source.list:

deb http://ports.ubuntu.com/ubuntu-ports bionic main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-security main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-updates main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-proposed main restricted universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports bionic-backports main restricted universe multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports bionic main restricted universe multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports bionic-security main restricted universe multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports bionic-updates main restricted universe multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports bionic-proposed main restricted universe multiverse
deb-src http://ports.ubuntu.com/ubuntu-ports bionic-backports main restricted universe multiverse
然后装一些基本的软件:

apt-get update
apt-get install sudo ifupdown net-tools ethtool udev wireless-tools iputils-ping resolvconf wget apt-utils wpasupplicant vim git gcc build-essential openssh-server
新建用户,就叫它ubuntu吧,密码也是ubuntu:

useradd -G sudo -m -s /bin/bash ubuntu
echo ubuntu:ubuntu | chpasswd
更改root密码:

passwd root
设置主机名为armhf:

echo armhf > /etc/hostname
设置网络,改/etc/network/interfaces文件:

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
终端配色:将/home/ubuntu/.bashrc里面的force_color_prompt=yes注释删掉即可。

设置默认挂载目录:改/etc/fstab,将启动分区挂载到/boot目录上:

/dev/mmcblk0p1 /boot vfat defaults 0 0
如果没什么别的想要配置的话,就可以exit退出了。

注意,因为Xilinx的内核配置默认将所有驱动都直接编译进内核,所以不需要将模块安装到文件系统中,就一个放在启动分区的内核就够了。

烧录SD卡
我们将镜像文件卸载:

sudo umount ./boot
sudo umount ./rootfs
sudo kpartx -d /dev/loop0
sudo losetup -d /dev/loop0
我们看到这个镜像文件有3.7G那么大,但是世界上它占用的磁盘空间没那么大,它是个sparse file,将它打包压缩之后就没看上去那么大了。可以用ls -s来看到它实际上多大:

$ ls -sh ubuntu1804.img
1.2G ubuntu1804.img
现在我们直接将这个文件dd到一张SD卡里面:

dd if=ubuntu1804.img of=/dev/sd某
如果你的SD卡不只有4G,那么可以通过像gparted、parted、fdisk等等的分区工具将第二个分区拉大,然后resize2fs重新设置分区大小。gparted一般会自动帮你resize2fs。

上机测试
可以从串口看到完整的启动过程:uboot、kernel、systemd,然后是login:

U-Boot 2018.01 (Apr 24 2019 - 00:24:09 +0800) Xilinx Zynq ZC702

Model: Zynq ZC702 Development Board
Board: Xilinx Zynq
Silicon: v3.1
I2C: ready
DRAM: ECC disabled 256 MiB
NAND: 128 MiB

...

Booting kernel from Legacy Image at 00008000 ...

Image Name: Linux-4.19.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4322424 Bytes = 4.1 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK

Flattened Device Tree blob at 00000000

Booting using the fdt blob at 0x000000
Loading Kernel Image ... OK
Loading Device Tree to 0eafd000, end 0eb037a6 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.19.0-xilinx (hyq@ict) (gcc version 6.2.1 20161114 (Linaro GCC Snapshot 6.2-2016.11))
#19 SMP PREEMPT Wed Apr 24 21:55:25 CST 2019
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: Xilinx ZC702 board

...

VFS: Mounted root (ext4 filesystem) on device 179:2.
devtmpfs: mounted
Freeing unused kernel memory: 1024K
Run /sbin/init as init process
random: fast init done
systemd[1]: System time before build time, advancing clock.
systemd[1]: Failed to insert module 'autofs4': No such file or directory
systemd[1]: systemd 237 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT
+UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2
default-hierarchy=hybrid)
systemd[1]: Detected architecture arm.

Welcome to Ubuntu 18.04 LTS!

systemd[1]: Set hostname to .
systemd[1]: File /lib/systemd/system/systemd-journald.service:36 configures an IP firewall (IPAddress
Deny=any), but the local system does not support BPF/cgroup based firewalling.
systemd[1]: Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loade
d unit using IP firewalling.)
random: systemd: uninitialized urandom read (16 bytes read)
systemd[1]: Reached target Swap.
[ OK ] Reached target Swap.

...

[ OK ] Started resolvconf-pull-resolved.service.

Ubuntu 18.04 LTS armhf ttyPS0

armhf login: ubuntu
Password:
Last login: Fri Apr 26 17:35:14 UTC 2019 on ttyPS0
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.19.0-xilinx armv7l)

ubuntu@armhf:~$
跑个screenfetch来看看:

sf
sf
gcc
gcc
gcc真的能用。。但是真是慢。。

参考资料
http://www.orangepi.org/Docs/Makingabootable.html
https://a-delacruz.github.io/debian/debian-arm64.html

@cisen
Copy link
Owner Author

cisen commented Jan 1, 2021

LED_BLINK

LED0  DATA3-15 P19
LED1 DATA3-17 U20
RES DATA3-11  P20
CLK SYS_CLK N18

约束文件(管教分配)

set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN U20 [get_ports {led[1]}]
set_property PACKAGE_PIN P19 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN P20 [get_ports rst_n]
set_property PACKAGE_PIN N17 [get_ports clk]
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/01/01 17:19:36
// Design Name: 
// Module Name: led_twinkle
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module led_twinkle(
    input clk,
    input rst_n,
    
    output [1:0] led
    );

reg [25:0] cnt;

assign led  = (cnt < 26'd2500_000) ? 2'b01 : 2'b10;

always @ (posedge clk or negedge rst_n) begin
    if (!rst_n)
        cnt <= 26'd0;
    else if(cnt < 26'd5000_000)
        cnt <= cnt + 1'b1;
    else 
        cnt <= 26'd0;
end
endmodule

@cisen
Copy link
Owner Author

cisen commented Jan 9, 2021

zynq7010之EBAZ4205入门改造

https://blog.csdn.net/weixin_42741023/article/details/103335948
第一章:改 SD 卡启动和改电源
在这里插入图片描述
20191201155641470

2、如果用 J4 的 6P 电源接口需要将背面的 D24 短接起来,或是焊接一个二极管就行,如下 图:
在这里插入图片描述
20191201155746139

或者把原来的二极管管取下来,然后焊接到上面,然后按照下面的飞线,这样就引出了12V 1路 3.3V 2路
在这里插入图片描述
20191201155810367

3、改 SD 卡启动,最简单的方法是将 R2577 短接起来,或者将 R2584 挪到 R2577 上,后面 要改成 nand 启动改回来就行了,如下图:
在这里插入图片描述

20191201160128547

1、串口位 J7,焊接 TX、RX、GND 就可以,波特率为 115200。SD 卡直接焊接就好。 2、JTAG 口为 J8,需要用到的引脚为: Pin1(GND) Pin2(Vref) Pin4(TMS) Pin6(TCK) Pin8(TDO) Pin10(TDI)
20191201160450683

在这里插入图片描述
3、如果需要添加 PL 端的晶振,电路图如下,R1372 焊一个 50 欧姆以下的电阻都可以,L29 可以直接短接起来,至于晶振的大小,根据自己的需要焊接一个 50MHz 以下的 3225 封装的 有源晶振就可以,FPGA 内部有 PLL,能够进行倍频。 在这里插入图片描述
20191201160653234
20191201160711260
20191201160745985

在这里插入图片描述
在这里插入图片描述
致辞此需要的已经·完成
给大家发一个自己做的vga,很丑
2019120116091647

20191201161155800

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Mexico-zyy-lost
Copy link

楼主,请教一下:“定制环境变量,改include/configs/zynq-common.h,主要是来配置启动参数。”这一段主要的修改内容是什么??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants