Xilinx Zynq ZC702学习总结

Xilinx zynq zc702开发:

一、zynq开发整个生态系统搭建:
1.基础资料获取:
https://github.com/Xilinx/
(包括:交叉编译工具,linux kernel源码,u-boot源码, device-tree源码, qemu, gdb等等)

http://www.wiki.xilinx.com/
(提供 了几乎所有的学习资料,包括:创建FSBL,配置编译内核,配置编译u-boot,编译生成dtb,制作根文件系统,linux 设备驱动程序,设计例程等等)

http://china.xilinx.com/support
(xilinx 官方提供的技术文档,非常祥尽)

http://xilinx.eetrend.com/category/1210
(xilinx中文社区,包含了大量的问题的解决方案)

2.运行pre-build image
拿到板子的第一步当然是先跑一下Pre-built images看看,一者可以验证板子好坏,再者可以看看Linux已经完成了哪些功能,做到了哪一步。
(主:参考文档:http://wiki.xilinx.com/
源码:http://git.xilinx.com/

最新的Pre-built images在http://wiki.xilinx.com/zynq-release-14-3
拷贝以下文件到SD卡上,SW16配置成00110,就可以在ZC702上启动Linux了。
BOOT.BIN
devicetree.dtb
uImage
uramdisk.image.gz

此时的硬件设备条件:只需要一台pc windows系统,开超级终端,链接开发板(无需驱动),上电启动,超级终端中显示整个启动过程,此时说明开发板是好的。接下来就是搭建自己的linux开发环境。

3.安装ubuntu 12.04(也可以是最新版)

4.安装git 和vim
由于xilinx的版本控制使用的git,这里先安装git下载u-boot、linux内核和开发包。

sudo apt-get install git git-email

sudo apt-get install vim

附加git使用技巧:
终端中输入:
$git clone git://github.com/Xilinx/<库名>
xilinx库概要:
库名: 库包含的内容:
linux-xlnx.git
/ 带有xilinx补丁和驱动的内核源码
u-boot-xlnx.git
/ 属性同上的xilinx官方u-boot源码
device-tree.git
/ 支持XSDK的设备树生成插件

5.安装并设置minicom
安装minicom:
$sudo apt-get install minicom

设置minicom
$sudo minicom -s

如果您的系统的默认语言不是英文,请执行下面的命令:
$LANG=EN
这样在接下来的设置中,minicom将以英文界面呈现在我们面前,操作起来比较方便
在系统终端输入“minicom -s”开始minicom的设置:
$minicom -s
其设置的主窗口的界面如下图:

Dialing directory......D run script (Go)........G | Clear Screen.............C
Send files.................S Receive files............R | cOnfigure Minicom..O
comm Parameters....P Add linefeed.............A | Suspend minicom.....J
Capture on/off..........L Hangup....................H | eXit and reset...........X
send break................F initialize Modem......M | Quit with no reset...Q
Terminal settings......T run Kermit...............K | Cursor key mode......I
lineWrap on/off........W local Echo on/off....E | Help screen...............Z
Paste file...................Y | scroll Back................B

进入“cOnfigure Minicom”选项设置串口参数,其界面如下图所示:
cOnfigure Minicom -> Serial port setup (进入串口设置) ->
(通过A、B、C...选择设置如下)
+-----------------------------------------------------------------------+
| A - Serial Device : /dev/ttyUSB0 |
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program : |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : No |
| G - Software Flow Control : No
|
| |
| Change which setting? |
+-----------------------------------------------------------------------+

设置完毕后退出到cOnfigure Minicom菜单 选择 Save setup as dfl(保存为默认设置)登录minicom:
$sudo minicom
设置minicom
$sudo minicom -s

如果您的系统的默认语言不是英文,请执行下面的命令:
$LANG=EN
这样在接下来的设置中,minicom将以英文界面呈现在我们面前,操作起来比较方便
在系统终端输入“minicom -s”开始minicom的设置:
$minicom -s
其设置的主窗口的界面如下图:
Dialing directory......D run script (Go)........G | Clear Screen.............C
Send files.................S Receive files............R | cOnfigure Minicom..O
comm Parameters....P Add linefeed.............A | Suspend minicom.....J
Capture on/off..........L Hangup....................H | eXit and reset...........X
send break................F initialize Modem......M | Quit with no reset...Q
Terminal settings......T run Kermit...............K | Cursor key mode......I
lineWrap on/off........W local Echo on/off....E | Help screen...............Z
Paste file...................Y | scroll Back................B

进入“cOnfigure Minicom”选项设置串口参数,其界面如下图所示:
cOnfigure Minicom -> Serial port setup (进入串口设置) ->
(通过A、B、C...选择设置如下)
+-----------------------------------------------------------------------+
| A - Serial Device : /dev/ttyUSB0
|
| B - Lockfile Location : /var/lock |
| C - Callin Program : |
| D - Callout Program : |
| E - Bps/Par/Bits : 115200 8N1 |
| F - Hardware Flow Control : No |
| G - Software Flow Control : No |
| |
| Change which setting? |
+-----------------------------------------------------------------------+

设置完毕后退出到cOnfigure Minicom菜单 选择 Save setup as dfl(保存为默认设置)

6.安装vivado
http://china.xilinx.com/support/download/index.htm
选择:Linux 64: Vivado 2014.2 Web 安装瘦客户端
$cd /下载目录下/
$chmod +x Xilinx_Vivado_SDK_2014.2_0612_1_Lin64.bin
(修改属性,添加可执行权限)
$./Xilinx_Vivado_SDK_2014.2_0612_1_Lin64.bin
(运行安装客户端)
若安装出现问题:dpkg-reconfigure dash 将dash改为bash,再次执行

7.安装交叉编译环境:
下载交叉编译工具:xilinx-2011.09-50-arm-xilinx-linux-gnueabi.bin
还有中方法是利用:petalinux工具
安装前一定要将dash改为bash,方法:
$dpkg -reconfigure dash
选择 no ,确定是bash shell

$cd /<下载目录>/
$chmod +x xilinx-2011.09-50-arm-xilinx-linux-gnueabi.bin
$./xilinx-2011.09-50-arm-xilinx-linux-gnueabi.bin

添加环境变量到 /etc/bash.bashrc 文件 方法如下:

打开bash.bashrc
$vim /etc/bash.bashrc

在打开的文件末尾加入如下内容:
export ARCH=arm
#(架构名字arm架构)
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
#(交叉编译工具名字)
export PATH=/root/CodeSourcery/Sourcery_CodeBench_Lite_for_Xilinx_GNU_Linux/bin/:$PATH
#(交叉编译工具的安装目录)
保存并退出

测试交叉编译工具是否安装成功方法如下:
$echo $PATH
(看输出的路径中是否含有交叉编译工具的安装路径)
$echo $CROSS_COMPILE
(看是否为:arm-xilinx-linux-gnueabi-)

8.在ubuntu系统下搭建TFTP服务
简介:TFTP是用来下载远程文件的最简单网络协议,它其于UDP协议而实现。嵌入式linux的tftp开发环境包括两个方面:一是linux服务器端的tftp-server支持,二是嵌入式目标系统的tftp-client支持。因为u-boot本身内置支持tftp-client,所以嵌入式目标系统端就不用配置了。
xinetd是新新一代的网络守护进程服务程序,经常用于管理多种轻量级网络服务,在这里也使用。

安装相关的软件包:ubuntu tftpd(服务端),tftp(客户端),xinetd
$sudo apt-get install tftpd tftp xinetd

建立配置文件
在/etc/xinetd.d/下建立一个配置文件tftp
$sudo vim tftp
#在打开的文件中输入如下内容:
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
#保存并退出。

接下来就是要建立ubuntu tftp服务文件目录(该目录是上传与下载文件的位置)
$sudo mkdir /tftpboot
#注意:该处建立的目录一定要和上一步建立的配置文件中的服务器参数:server_args = -s /tftpboot 一致,服务器配置文件中指定了 /tftpboot 文件目录作为服务器目录。
$sudo chmod 777 /tftpboot -R
#该出目的是要修改(-R: Recursive)tftpboot目录权限,便于我们get和put

重启tftp服务
$sudo /etc/init.d/xinetd restart
至此ubuntu tftp服务已经安装配置完成

最后我们测试下我们的tftp服务:
get:是从tftp服务端获取文件,前提是要确保:要获取的这个文件在/tftpboot目录中,且权限是777
put:是想tftp服务端添加文件,前提条件是要在服务端/tftpboot目录中见一个同名空白文件且权限777,是使用put后,会将文件内容通过tftp协议写入服务端的同名文件中
操作如下:
$cd /tftpboot
$touch 1.c 2.c
&vim 1.c
#随意输入些内容 保存推出, 2.c不变是个空白文档
#然后cd到其他如何一个目录除了/tftpboot目录 假定/tmp
$cd /tmp
$touch 2.c
$vim 2.c
#在这个2.c中输入任意内容
$tftp 192.168.5.10
#ip是自己pc的ip地址,进入tftp服务 显示:tftp>
tftp>get 1.c
#发现在自己的/tmp目录下多了一个1.c文件,打开1.c,检查内容
tftp>put 2.c
#这是已经将/tmp下的2.c文件的内容传到了/tftpboot/2.c的文件
#检查/tftpboot/2.c
tftp>q #接着回车键退出tftp
$cat /tftpboot/2.c
#发现原来空白文档2.c有了内容,
#至此所有的tftp服务的配置和测试都已结束

9.搭建nfs服务器
简介:nfs就是network filesystem的缩写,它最强大的功能就是可以通过网络让不同的机器,和不同的操作系统彼此共享文件——可以通过NFS挂载远程主机的目录,访问该目录就像访问本地目录一样,所以也可以简单的将它看作一个文件服务器(FileServer)。
/etc/exports
对NFS服务的访问是由exports来批准,它枚举了若干有权访问NFS服务器上文件系统的主机名。
/装NFS客户端(可选)
$ sudo apt-get install nfs-common

NFS配置:
ubuntu下nfs的挂载目录及权限在文件/etc/exports中进行定义:
方法:
$vim /etc/exports
#添加如下内容:
/rootnfs *(rw,sync,no_root_squash)

######解释: ‘*’:表示所有网络都可以访问/rootnfs
######/rootnfs 192.168.1.*(rw,sync,no_root_squash) #表示只有该网段的所有用户可以访问
######/rootnfs 表示要共享的目录,rw:表示可以读写权限,sync:表示资料同步写入内存和硬盘,no_root_squash是nfs客户端分享目录使用者的权限

建立一个/rootnfs目录
$mkdir /rootnfs
$chmod 777 /rootnfs -R

启动nfs服务:
$sudo /etc/init.d/nfs-kernel-server start

或者重启nfs服务:
$sudo /etc/init.d/nfs-kernel-server restart
或者:
$sudo service nfs-kernel-server restart

测试:随便拷贝或建立几个文档到/nfsroot下
$umount /mnt
#确保/mnt下没有挂载任何东西
$mount -t nfs -o nolock 192.168.5.10:nfsroot /mnt
#等待挂载完成后
$ls /mnt
看是否有了与/nfsroot相同的内容

至此,xilinx zynq开发环境已经搭建完成,接下来就从启动的过程来详述各种文件制作

二、zynq系列启动linux方式介绍
两种引导方式:
.主引导方式
.从引导方式

主引导方式:
不同的非易失的存储器介质如:QSPI ,NAND,NOR flash还有SD卡用来存储引导镜像。cpu会从上述存储器中引导镜像到处理器端,主引导方式分为安全和非安全的启动模式

引导过程是ARM cortex-A9双核中的一个核去执行片上ROM的代码,该部分的代码负责加载第一阶段的boot loader (FSBL)。
第一阶段的boot loader所做的工作是:
.如果有bitstream,就会配置FPGA,如果没有就不配置
.配置MIO接口
.初始化DDR控制器
.初始化PLL时钟
.从非易失存储器中加载执行linux u-boot镜像程序

u-boot加载后就会从非易失存储器中加载内核镜像,根文件系统,设备树到DDR中执行。结束linux的引导过程

从引导方式:
JTAG方式只能用作从引导方式。一个外部PC作为宿主机通过JTAG的方式引导内核到片上存储器。在引导过程中,PS端cpu保持空闲模式。从引导方式是一种非安全的引导方式。
种模式下cpu会停止所有的工作,只使能JTAG接口,必须把所有的启动相关的镜像文件下载到存储器中才能再次启动cpu
JTAG启动过程:
boot ROM----->FSBL------>load bitstream------>load and execute u-boot------>load linux kernel------>load device tree----->load root file system----->rum all

三、详细介绍启动过程中各个文件制作:
.FSBL (启动过程第一阶段的bootloader)
.bit文件 ( 用于初始化FPGA,可以没有)
.u-boot.elf (编译uboot生成的u-boot可执行文件)
.BOOT.BIN (用于sd卡启动的引导程序)
.devicetree.dtb (编译设备树dts文件生成)
.uImage (编译内核生成)
.uramdisk.image.gz
(文件系统)

1.FSBL:
.打开 SDK软件

.File > New > Application Project

配置该应用工程:
如: 工程名: zynq_fsbl_0

存储路径:(自由选择,可以选择此为默认)
硬件平台: xynq 702_hw_platform
处理器: PS7_cortexa9_0

系统平台:无(standalone)
语言: c语言
BSP: Select Create New
名字:zynq_fsbl_0_bsp

点next 可以选择获取例程:Zynq FSBL

.点击完成
sdk会自动编译生成 zynq_fsbl_0.elf文件

2. .bit文件生成
通过vivado 来生成fpga端的配置文件

3. u-boot.elf
编译u-boot过程:
3.1从git仓中下载u-boot源码:
$git clone git://git.xilinx.com/u-boot-xarm.git
$cd u-boot-xarm

3.2配置编译u-boot
配置过程:
$make zynq_zc70x_config

编译过程:
$make

或者,配置加编译一起搞定
$make zynq_zc70x

3.3编译完成后一定要对其重命名
mv ./u-boot ./u-boot.elf

4.编译内核
4.1获取内核源码:
方法:
1.终端:$git clone git://github.com/Xilinx/linux-xlnx.git
这种方式总能够获取最新的内核源码,但是我们在研发过程中最新的内核源码未必是件好事,尤其是对于内核不了解的新人来说,找一个稳定、且应用广泛的版本才是最重要的,这里我们选取3.10版本的内核,因为这个版本的内核目前应用最为广泛,这就意味着遇到问题是我们能够获取的资源最多。
2.获取3.10.xx版本的方法:(此法当然可以获取其他版本内核)
https://github.com/Xilinx/linux-xlnx/releases/tag/xilinx-v14.7
选择:source code (tar.gz)
$cd /<下载目录>
$tar -xvf linux-xlnx-xilinx-v14.7
等待解压完成后
$cd linux-xlnx-xilinx-v14.7

4.2配置和编译内核:
1.配置内核过程:
配置过程的通用方法:
make ARCH=
// arm架构 xilinx_zynq_defconfig
或:make ARCH= (menu|x|n)config ()
// arm架构 menuconfig
此处而言指令如下:
$make ARCH=arm xilinx_zynq_defconfig
$make ARCH=arm menuconfig

此处我们之前已经配置好了交叉编译环境,查看环境变量:
$echo $ARCH
显示 arm 那么我们完全可以直接输入:
$make xilinx_zynq_defconfig
$make menuconfig
这时就会进入到内核编译前的配置页面,选择自己想要编入到内核的模块。
4.3编译内核:
make ARCH=arm UIMAGE_LOADADDR=0x8000 uImage -j4
-j4 :表示4核同时编译,可以加快编译速度

5. devicetree.dtb文件制作
准备工具:
XPS
SDK

输入文件:
硬件工程目录
linux 源码目录

输出文件:
*.dts *.dtb
具体实施如下:
5.1、创建一个设备树源文件(.dts)
1.打开SDK
2.从git 库中下载设备树的mld文件和tcl文件
git clone git://github.com/Xilinx/device-tree.git
3.在SDK中添加BSP库
Xilinx Tools > Repositories > New... (下载的设备树mld,tcl文件所在路径) > OK
4.创建一个板级支持包(BSP)
File > New > Board Support Package >
选择Board Support Package OS: device-tree > Finish
5.会出现一个窗口(在打开的设备树system.mss文件中,点击“modify BSP's setting”同样会出现)

点击完成后会在//
/libsrc/device tree_v1_01_b/xilinx.dts.

另一种获取.dts 设备树源文件的方式,在linux内核源码中linux-xlnx/arch//boot/dts/<找到适合zynq的dts>/

5.2、编译设备树dts文件生成 .dtb文件
cd 内核源码目录下

make ARCH=arm dtbs

DTC工具会自动编译内核中所有的arm类的dts文件生成 dtb文件
在目录<内核源码>/arch/arm/boot/dts/ 查看过于zynq的dtb文件

指定某一dts文件生成dtb文件:

/kernel1/linux-xlnx/scripts/dtc/dtc -I dts -O dtb -o zynq-zc706.dtb /kernel1/linux-xlnx/arch/arm/boot/dts/zynq-zc706.dts
<工具路径--参数指明由dts生成dtb--生成的dtb文件名--源的路径和名字>

在zynq zc702的板子上指令如下:
/home/klaus/Learnning/KERNEL/linux-xlnx-xilinx-v14.7/scripts/dtc/dtc -I dts -O dtb -o zynq-zc702.dtb /home/klaus/Learnning/KERNEL/linux-xlnx-xilinx-v14.7/arch/arm/boot/dts/zynq-zc702.dts

6、生成BOOT.BIN
6.1打开SDK
6.2选择Create Zynq Boot Image
6.3指定一个路径这个路径用来存储生成的BIF文件
6.4在Boot image partitions中添加在路径中选择
zynq_fsbl_0.elf 类型为:bootloader
xxx.bit 用于初始化fpga的bit文件可以不加,类 型:默认
u-boot.elf 类型:默认
6.5确定输出路径,文件名:BOOT.bin。点击确定生成

7.uramdisk.image.gz文件系统修改
uramdisk是基于ram的文件系统,是xilinx官方给我们提供的小巧实用的文件系统。包含了基本的shell指令,我们在这可以直接使用而不用直接创建,通过修改来满足自己的需求即可。接下来详细阐述修改方法:

这里涉及到ramdisk.image.gz和uramdisk.image.gz两中类型,区别:
uramdisk是在ramdisk的基础上添加了64k的uboot的头信息:
uramdisk转为ramdisk的方式:
dd if=./uramdisk.image.gz of=./ramdisk.image.gz skip=16 bs=4

具体操作如下:
1.下载uramdisk.image.gz
http://www.wiki.xilinx.com/Zynq+Release+14.3 (下载最新的uramdisk.image.gz或ramdisk.image.gz)

2.将uramdisk->ramdisk
$dd if=./uramdisk.image.gz of=./ramdisk.image.gz skip=16 bs=4

3.将ramdisk文件解压:
$gunzip ramdisk.image.gz (生成ramdisk.image)

4.挂载镜像:
$chmod u+rwx ramdisk.image
$mkdir tmp_mnt
$sudo mount -o loop ramdisk.image tmp_mnt/
$cd tmp_mnt/

5.这时就可以在挂载的文件系统中做修改了。
添加一个自动挂载文件系统的shell,使其在下次启动时能够在动挂载网络文件系统或ext4文件系统。

6.卸载文件系统将其压缩成镜像文件:
$sudo umount tmp_mnt
$gzip ramdisk.image

7.将修改完后的ramdisk->uramdisk
$mkimage -A arm -T ramdisk -C gzip -d ramdisk.image.gz uramdisk.image.gz

四、SD卡方式启动:
SD卡的启动方式是今后开发的产品的首选启动方式。在这里做详细的阐述。所需要的文件包括:
BOOT.BIN
devicetree.dtb
uImage
ramdisk.image.gz

首先要制作一个启动sd卡:
插入SD卡后终端中输入:
$dmesg
最后一行显示SD卡可用的信息

//在保存sd卡的分区表的时候磁盘分区工具有时不会擦除第一扇区的几个字节,使用 dd 指令擦除

//终端输入:
$ if=/dev/zero of=/dev/sdX bs=1024 count=1

$fdisk /dev/mmcblk0 (真对于大卡)

$fdisk /dev/sdb (对于micro sd用U口的读卡器读写)
提示:输入m显示帮助

输入m后回车显示:
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
命令:p (查看sd有无分区)
如有则:
命令:d (删除之前的分区,按照提示信息逐步操作(1-4顺次删除))
删除完后:
命令(输入 m 获取帮助): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
分区号 (1-4,默认为 1): 1
起始 sector (2048-15523839,默认为 2048): 2048
Last sector, +扇区 or +size{K,M,G} (2048-15523839,默认为 15523839):+500M

相同的操作将剩余的空间分配给第二分区
命令(输入 m 获取帮助): t
分区号 (1-4): 1
Hex code (type L to list codes): L
0 空 24 NEC DOS 81 Minix / 旧 Linu bf Solaris
1 FAT12 27 Hidden NTFS Win 82 Linux 交换 / So c1 DRDOS/sec (FAT-
2 XENIX root 39 Plan 9 83 Linux c4 DRDOS/sec (FAT-
3 XENIX usr 3c PartitionMagic 84 OS/2 隐藏的 C: c6 DRDOS/sec (FAT-
4 FAT16 <32M 40 Venix 80286 85 Linux 扩展 c7 Syrinx
5 扩展 41 PPC PReP Boot 86 NTFS 卷集 da 非文件系统数据
6 FAT16 42 SFS 87 NTFS 卷集 db CP/M / CTOS / .
7 HPFS/NTFS/exFAT 4d QNX4.x 88 Linux 纯文本 de Dell 工具
8 AIX 4e QNX4.x 第2部分 8e Linux LVM df BootIt
9 AIX 可启动 4f QNX4.x 第3部分 93 Amoeba e1 DOS 访问
a OS/2 启动管理器 50 OnTrack DM 94 Amoeba BBT e3 DOS R/O
b W95 FAT32 51 OnTrack DM6 Aux 9f BSD/OS e4 SpeedStor
c W95 FAT32 (LBA) 52 CP/M a0 IBM Thinkpad 休 eb BeOS fs
e W95 FAT16 (LBA) 53 OnTrack DM6 Aux a5 FreeBSD ee GPT
f W95 扩展 (LBA) 54 OnTrackDM6 a6 OpenBSD ef EFI (FAT-12/16/
10 OPUS 55 EZ-Drive a7 NeXTSTEP f0 Linux/PA-RISC
11 隐藏的 FAT12 56 Golden Bow a8 Darwin UFS f1 SpeedStor
12 Compaq 诊断 5c Priam Edisk a9 NetBSD f4 SpeedStor
14 隐藏的 FAT16 <3 61 SpeedStor ab Darwin 启动 f2 DOS 次要
16 隐藏的 FAT16 63 GNU HURD or Sys af HFS / HFS+ fb VMware VMFS
17 隐藏的 HPFS/NTF 64 Novell Netware b7 BSDI fs fc VMware VMKCORE
18 AST 智能睡眠 65 Novell Netware b8 BSDI swap fd Linux raid 自动
1b 隐藏的 W95 FAT3 70 DiskSecure 多启 bb Boot Wizard 隐 fe LANstep
1c 隐藏的 W95 FAT3 75 PC/IX be Solaris 启动 ff BBT
1e 隐藏的 W95 FAT1 80 旧 Minix
code (type L to list codes): b
Changed system type of partition 1 to b (W95 FAT32)
将500M的地分区作为一个引导分区

同样的方式修改第二分区的系统ID
命令(输入 m 获取帮助): t
分区号 (1-4): 2
Hex code (type L to list codes): 83
这样就把剩余的空间作为linux的第二分区,可用来存放文件系统和其他数据等
Hex code (type L to list codes): b
Changed system type of partition 1 to b (W95 FAT32)
将500M的地分区作为一个引导分区

同样的方式修改第二分区的系统ID
命令(输入 m 获取帮助): t
分区号 (1-4): 2
Hex code (type L to list codes): 83
这样就把剩余的空间作为linux的第二分区,可用来存放文件系统和其他数据等

命令: w
将分区表写入到sd,并退出。

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

注:如果是对小卡的操作
$sudo mkfs.vfat -F 32 -n boot /dev/sdb1
$mkfs.ext4 -L root /dev/sdb2

sd卡的分区操作结束,将之前生成的BOOT.BIN, devicetree.dtb, uImage, uramdisk.image.gz拷贝到sd卡的第一分区;

将zynq zc702开发板的sw16拨码开发组调至:00110选择成为sd卡启动方式

连接各个连接线,包括电源线,usb转串口线,网线

开终端;输入:$sudo minicom;打开minicom

检查无误后,上电。终端中显示启动过程。

注意:我们在这里只是启动加载的是uramdisk的文件系统,那开发过程中我们更多的还是会利用nfs网络文件系统,那么在sd卡启动过程中怎么加载网络文件系统,还有就是我们要自动挂载第二分区的问题, 这些是我们必须要解决的问题

sd卡启动过程中用tftp加载内核和设备树以及自动加载nfs网络文件系统的方法:
1. 修改u-boot,用tftp加载kernel和device tree,用nfs加载rootfs
修改include/configs/zynq_common.h(注意:同时要关注zynq_zc70x.h)中的IP Address的配置为需要的值
/* Default environment */
#define CONFIG_IPADDR 10.10.70.102
#define CONFIG_SERVERIP 10.10.70.101
以上是u-boot中默认的环境变量的配置,当然可以修,比如:设置开发板的IP:192.168.5.20;主机服务器的IP:192.168.5.10

修改include/configs/zynq_common.h中关于sdboot的配置为
"sdboot=echo Copying Linux from tftp to RAM...;" \
"tftp 0x3000000 ${kernel_image};" \
"tftp 0x2A00000 ${devicetree_image};" \
"bootm 0x3000000 0x2000000 0x2A00000\0" \

保存并退出,这样再次编译u-boot,重新生成BOOT.BIN。按照上面阐述的sd引导方式,再做一边。就能实现sd引导实现从tftp服务段下载kernel image和设备树了
注意:实现tftp下载内核和设备树在开发中并不是必须的,我们完全可以利用sd中BOOT.BIN,uImage, devicetree.dtb实现引导内核的启动,利用内核加载nfs

2.实现nfs网络文件系统的加载:
确认内核里面已经包含NFS Client的支持
File Systems->Network File Systems
File Systems->Network File Systems->NFS Client support
File Systems->Network File Systems->NFS Client support-> NFS Client support for NFS version 3
File Systems->Network File Systems->Root file system on NFS
保险起见可以重新编译内核,正常情况下内核已经对NFS做了支持

为了让内核顺利加载nfs,还需要告诉内核我想要加载的是nfs,而不是其他文件系统。那么就要修改bootargs参数。在设备树的源文件.dts中:
$cd /
$vim /arch/arm/boot/dts/zynq-zc702.dts
打开zc-702的dts源码,第27行:
chosen {
// bootargs = "console=ttyPS0,115200 root=/dev/ram rw ip=192.168.5.20:::255.255.255.0:ZC702:eth0 earlyprintk";
bootargs = "noinitrd console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.5.10:/nfsroot,nolock ip=192.168.5.20 rw earlyprintk";

linux,stdout-path = "/amba@0/serial@e0001000";
} ;
做如上所示修改:将原来的bootargs 注释掉,加上新的bootargs:
bootargs = "noinitrd console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.5.10:/nfsroot,nolock ip=192.168.5.20 rw earlyprintk";
解释:noinitrd:因为ramdisk的优先级比nfs网络文件系统要高,所以加noinitrd不按照原先设定的优先级进行加载;
console=ttyPS0:表示串行控制终端
115200:表示串口波特率
root=/dev/nfs:表示告诉内核要加载的文件系统是nfs网络文件系统
nfsroot=192.168.5.10:/nfsroot:告诉内核要加载的网络文件系统的位置,会自动寻找ip为 192.168.5.10的网络主机,并找到/nfsroot这个目录。
nolock:在挂载nfs的时候必须要使用参数 -o nolock 无锁模式。举例:
将 192.168.5.10:/nfsroot挂载到/mnt下:sudo mount -o nolock 192.168.5.10:/nfsroot /mnt (需要加一个 -o nolock 或 -t nfs)
ip=192.168.5.20:是开发板的ip地址,即:nfs客户端的ip
rw:表示客户端的权限有着可读可写权限
earlyprintk:与终端打印信息相关

这样修改完毕后,保存退出,因为我们修改了.dts文件,故而重新编译生成.dtb文件。将新生成的dtb文件拷贝到sd,将之前的覆盖掉,重新上电,启动。验证加载的是nfs而不是ramdisk:
minicom终端中输入
zynq>ls /
etc linuxrc root update_qspi.sh
README home mnt sbin usr
bin lib opt sys var
dev licenses proc tmp
在pc端:ctrl+alt+t新打开一个终端
$cd /nfsroot
$mkdir /123456
新建一个文件夹名字123456
$ls /nfsroot
123456 dev home licenses mnt proc root sys update_qspi.sh var
bin etc lib linuxrc opt README sbin tmp usr

再回到minicom终端:
ls
123456 etc linuxrc root update_qspi.sh
README home mnt sbin usr
bin lib opt sys var
dev licenses proc tmp
发现在我们的minicom端出现了:123456的文件夹,说明成功加载了nfs网络文件系统

3.加载sd第二分区的ext4文件系统:
这里通过利用sd卡引导内核来实现ext4文件系统的加载,加载ext4文件系统的好处是可以加载大型的带有图形界面的文件系统。
需要的文件:1.BOOT.BIN
2.devicetree.dtb
3.uImage
4.ramdisk.image.gz
5.Linaro的跟文件系统(拷贝到sd卡的ext4分区,当然这里的文件系统可以用其他的例如:前面ramdisk的文件系统)
1-4文件拷贝到sd的fat分区
注意:
Devicetree的地址是bootm的第三个参数,所以用bootm启动时第二个参数(ramdisk的地址)就不能少。如果不加载ramdisk,就会出现ramdisk校验问题。所以现在还要做一次无用的ramdisk加载,以骗过bootm。这就是为什么我们加载ext4文件系统,还要有ramdisk.image.gz的原因了。
要启动ext4关键在于:设置bootargs参数
bootargs=noinitrd console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1
设置bootargs的方式有两种:
1.通过修改dts文件:
$cd /<内核源码目录>
$vim arch/arm/boot/dts/zynq-zc702.dts
chosen {
bootargs = "noinitrd console=ttyPS0,115200
root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4
rootwait devtmpfs.mount=1";
linux,stdout-path = "/amba@0/serial@e0001000";
} ;
保存退出
重新编译/home/klaus/Learnning/KERNEL/linux-xlnx-xilinx-v14.7/scripts/dtc/dtc -I dts -O dtb -o zynq-zc702.dtb /home/klaus/Learnning/KERNEL/linux-xlnx-xilinx-v14.7/arch/arm/boot/dts/zynq-zc702.dts
黑体标记出来工具的路径,必要参数, 生成的文件名,源文件的路径

将生成的dtb文件重新拷贝到sd卡,将之前的dtb文件覆盖,在确保u-boot启动的环境变量中没有bootargs值就可以顺利启动。

2.不修改dts文件,直接在u-boot引导过程中设置环境变量bootargs的值,方法如下:
上电后,3秒内按下任意键,进入u-boot的设置模式。
zynq-uboot> pri
baudrate=115200
bootcmd=run sdboot
bootdelay=3
devicetree_image=devicetree.dtb
devicetree_size=0x20000
ethact=Gem.e000b000
ethaddr=00:0A:35:02:73:D5
fdt_high=0x20000000
fileaddr=2a00000
filesize=243d
initrd_high=0x20000000
ipaddr=192.168.5.20
jtagboot=echo TFTPing Linux to RAM...;tftp 0x3000000 ${kernel_image};tftp 0x2A00000 ${devicetree_image};tftp 0x2000000 ${ramdisk_image};bootm 0x3000000 0x2000000 0
kernel_image=uImage
kernel_size=0x500000
modeboot=sdboot
nandboot=echo Copying Linux from NAND flash to RAM...;nand read 0x3000000 0x100000 ${kernel_size};nand read 0x2A00000 0x600000 ${devicetree_size};echo Copying ram0
norboot=echo Copying Linux from NOR flash to RAM...;cp 0xE2100000 0x3000000 ${kernel_size};cp 0xE2600000 0x2A00000 ${devicetree_size};echo Copying ramdisk...;cp 00
qspiboot=echo Copying Linux from QSPI flash to RAM...;sf probe 0 0 0;sf read 0x3000000 0x100000 ${kernel_size};sf read 0x2A00000 0x600000 ${devicetree_size};echo 0
ramdisk_image=uramdisk.image.gz
ramdisk_size=0x5e0000
sdboot=echo Copying Linux from SD to RAM...;mmcinfo;fatload mmc 0 0x3000000 ${kernel_image};fatload mmc 0 0x2A00000 ${devicetree_image};fatload mmc 0 0x2000000 ${0
serverip=192.168.5.10
stderr=serial
stdin=serial
stdout=serial

Environment size: 1719/131068 bytes

发现没有bootargs环境变量的值,设置:
zynq-uboot>set bootargs “noinitrd console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1”
zynq-uboot>sav
保存
zynq-uboot>reset
重启uboot
这时我们发现成功加载了linaro的文件系统,此系统是带有图行界面的

saned disabled; edit /etc/default/saned
Last login: Thu Nov 25 16:25:31 UTC 2010 on tty1
run-parts: /etc/update-motd.d/98-fsck-at-reboot exited with return code 1
Welcome to Linaro 12.06 (GNU/Linux 3.10.0-xilinx armv7l)

* Documentation: https://wiki.linaro.org/

0 packages can be updated.
0 updates are security updates.

0 packages can be updated.
0 updates are security updates.

root@linaro-ubuntu-desktop:~# pwd
/root
root@linaro-ubuntu-desktop:~# cd /
root@linaro-ubuntu-desktop:/# ls
Iamext4 boot etc lib media opt root sbin srv tmp var
bin dev home lost+found mnt proc run selinux sys usr

4.挂载sd的第二分区ext4和nfs:
除了直接启动加载的方式外,我们还可利用挂载的方式,挂载的方式也是一种非常方便的方式.具体的方法阐释:
修改uramdisk.image.gz
修改启动文件
重新上电检测

详细过程如下:
修改uramdisk.image.gz:
$dd if=./uramdisk.image.gz of=./ramdisk.image.gz skip=16 bs=4
记录了1326797+0 的读入
记录了1326797+0 的写出
5307188字节(5.3 MB)已复制,2.08534 秒,2.5 MB/秒
说明已经成功生成了ramdisk.image.gz

解压ramdisk.image.gz->ramdisk.image
$gunzip ramdisk.image.gz

将生成的ramdisk.image挂载到/mnt目录
$umount /mnt
$mount ramdisk.image /mnt

建立一个ext4文件系统的挂载点
$cd /mnt
$mkdir /mnt/ext4fs

修改启动shell文件,使其在启动过程中自动挂载
$vim /mnt/etc/init.d/rcS
在文件末尾添加如下内容:
mount -t nfs -o nolock 192.168.5.10:/nfsroot /mnt
mount -t ext4 /dev/mmcblk0p2 /ext4fs
echo “ext4 nfs mounted”
保存退出

卸载/mntmkimage -A arm -T ramdisk -C gzip -d ramdisk.image.gz uramdisk.image.gz
Image Name:
Created: Tue Jul 22 13:30:15 2014
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 5307212 Bytes = 5182.82 kB = 5.06 MB
Load Address: 00000000
Entry Point: 00000000
umount /mnt

将ramdisk->uramdisk的操作:
先将ramdisk.image压缩:
$gzip ramdisk.image
在将ramdisk.image.gz->uramdisk.image.gz
$mkimage -A arm -T ramdisk -C gzip -d ramdisk.image.gz uramdisk.image.gz
显示:
Image Name:
Created: Tue Jul 22 13:30:15 2014
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 5307212 Bytes = 5182.82 kB = 5.06 MB
Load Address: 00000000
Entry Point: 00000000
这时我们自己修改的uramdisk.image.gz就可以使用了,重新拷贝到sd卡,设置dts的bootargs的值使其不要加载nfs,就ok了。启动后利用类似与nfs的检测方式检测是否挂载成功

五、数据的传输测试
测试的目的是要实现:
1、数据由pc端写入到sd卡的第二分区
2、数据由sd卡的第二分区读出到pc端
这里选用内核加载ramdisk,然后将sd第二分区挂载到uramdisk的方式。根据之前阐述的制作uramdisk的方法,在该文件系统根目录下建立一个ext4fs的文件夹。作为ext4文件系统的挂载点。并在启动shell中添加挂载的指令。方法同(四、4.自动挂载ext4和nfs的修改一样)

注意:bootargs = "console=ttyPS0,115200 root=/dev/ram rw ip=192.168.5.20:::255.255.255.0:ZC702:eth0 earlyprintk";
启动:
测试网络:
zc702端ping PC
zynq>ping 192.168.5.10
显示延迟时间正常 ctrl+c终止ping

PC端ping zc702
$ping 192.168.5.20
显示延迟时间正常 ctrl+c终止ping

数据传输ftp方式:
$sudo ftp 192.168.5.20
Connected to 192.168.5.20.
220 Operation successful
Name (192.168.5.20:klaus):
230 Operation successful
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
这时输入 ‘?’就可查看ftp的所有指令
ftp> ?
Commands may be abbreviated. Commands are:
! dir mdeleteqc
site
$ disconnect mdir sendport size
account exit mget put status
append form mkdir pwd struct
ascii get mls quit system
bell glob mode quote sunique
binary hash modtime recv tenex
bye help mput reget tick
case idle newer rstatus trace
cd image nmap rhelp type
cdup ipany nlist rename user
chmod ipv4 ntrans reset umask
close ipv6 open restart verbose
cr lcd prompt rmdir ?
delete ls passive runique
debug macdef proxy send
以上就是ftp服务所支持的所有指令.其中get put指令可以用来传输文件。举例:

put实例:
$cd /tftpboot
$ls
BOOT.bin devicetree.dtb stub.tcl uImage
create_devicetree.sh~ ps7_init.tcl u-boot.elf uramdisk.image.gz
把该目录下的uImage拷贝到sd第二分区/Iamext4
$ftp 192.168.5.20
进入ftp服务
ftp>mkdir /ext4fs/Iamext4
ftp>cd /ext4fs/Iamext4
ftp>put uImage
local: uImage remote: uImage
200 Operation successful
150 Ok to send data
226 Operation successful
3124688 bytes sent in 0.27 secs (11198.7 kB/s)
说明文件传输成功。验证:在minicom中
zynq> ls ext4fs/Iamext4/
uImage
成功

get实例:
在sd卡第二分区的Iamext4目录下加一个get.c的文件内容123456,然后将该文件传到PC端的/tftpboot目录下然后读取内容看是否正确

minicom终端中
zynq>touch /ext4fs/Iamext4/get.c
zynq>vi /ext4fs/Iamext4/get.c
出入123456 保存并退出
zynq>cat /ext4fs/Iamext4/get.c
123456
说明文件建立成功。

PC端
$cd /tftpboot
$ls
BOOT.bin devicetree.dtb stub.tcl uImage
create_devicetree.sh~ ps7_init.tcl u-boot.elf uramdisk.image.gz
没有get.c
$ftp 192.168.5.20
Connected to 192.168.5.20.
220 Operation successful
Name (192.168.5.20:klaus): klaus
230 Operation successful
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /ext4fs/Iamext4
ftp> get get.c
local: get.c remote: get.c
200 Operation successful
150 Opening BINARY connection for get.c (7 bytes)
226 Operation successful
7 bytes received in 0.00 secs (61.6 kB/s)
这里显示传输成功。验证:

ctrl+alt+t新打开一个终端
$cd /tftpboot
$ls
BOOT.bin get.c u-boot.elf
create_devicetree.sh~ ps7_init.tcl uImage
devicetree.dtb stub.tcl uramdisk.image.gz
发现有了get.c文件,进一步验证
$cat get.c
123456
说明成功了

2.ssh的方式传输文件
我们的加载的文件系统中默认用户:root 密码root

将pc端文件拷贝到远程服务器上:
cd /tftpboot
$ scp get.c root@192.168.5.20:/ext4fs/tmp
root@192.168.5.20's password:
get.c 100% 7 0.0KB/s 00:00

将开发板的sd第二分区的/tmp/get.c拷贝到pc端/home/klaus目录
$scp 192.168.5.20:/tmp/get.c /home/klaus/
root@192.168.5.20's password:
get.c 100% 7 0.0KB/s 00:00
验证的方法同上

原文链接: http://blog.csdn.net/klaus_wei/article/details/38063349

1 条评论

(1楼)Xilinx zynq zc702学习总结

由 匿名用户 在 星期二, 11/28/2017 - 09:51 发表。

Xilinx zynq zc702学习总结 部分内容更正

在写zynq系列学习总结的时候,由于过于匆忙今天回头看的时候还是有些问题的,而这些问题可能会给读者尤其是初学者带来很大的困扰

1.必须要清楚一点就是:ramdisk..... 和 uramdisk 的区别,zImage和uImage的区别,uramdisk,uImage是与uboot有着联系的。
文中没有说明白uImage的制作过程,制作uImage必须要使用的工具就是mkimage工具,这个工具是怎么来的来,它来自于:
.编译uboot时在uboot源码目录下tools目录会产生mkimage.
.修改权限:sudo chmod 777 mkimage
.sudo cp mkimage /usr/bin
就可以使用mkimage工具来制作uImage来