zedboard 配置一个带NFS文件系统的内核和开机自动挂载sd卡

一路上看着n多遍的官方文档和各路大神的文档,总算编译成功,把心酸记录一下,为以后自己的使用方便

先把官方文档挂上

http://www.wiki.xilinx.com/U-boot

http://www.wiki.xilinx.com/Build+kernel

http://www.wiki.xilinx.com/Build+and+Modify+a+Rootfs

http://www.wiki.xilinx.com/Build+Device+Tree+Blob

环境为Ubuntu12.04

目标版 zedboard

 

目前system.bit文件尚未编译,用的是官方的版本。

 

目录

、交叉编译工具的安装

2uboot的编译

3NFS内核的编译

4、根文件系统的制作和修改

6qt的编译

7opencv的编译安装

、交叉编译工具的安装

首先安装交叉编译工具,xilinx-arm-gcc/g++

由于官方目前把工具撤了,换成了其他的东西,装那个肯定行,不过还是习惯直接安装

 https://secure.xilinx.com/webreg/login.do?oamProtectedResource=wh%3Dwww.xilinx.com%20wu%3D%2Fmember%2Fmentor_codebench%2Farm-2010.09-62-arm-xilinxa9-linux-gnueabi.bin%20wo%3D1%20rh%3Dhttp%3A%2F%2Fwww.xilinx.com%20ru%3D%252Fmember%252Fmentor_codebench%252Farm-2010.09-62-arm-xilinxa9-linux-gnueabi.bin

安装时会提示会提示需要bash,而Ubuntu为了提高速度,默认把shell改成了dash,那么需要先改回来(如果在centos下则不需要那么麻烦)

 

sudodpkg-reconfigure dash

然后选择否

sudo./xilinx-2011.09-50-arm-xilinx-linux-gnueabi.bin

好了,接下来是一个图形安装界面,肯定很熟悉啦

安装完之后,设置环境变量吧

当前用户在~/.bashrc下。但是后面的安装需要权限,所以会造成很多问题

我就是栽在这里很多时间啊

那么直接修改 /etc/profile

sudo vi/etc/profile

在最后添加上

exportPATH=/path/to/cross/compiler/bin:$PATH  # 前面 为你的安装路径

exportCROSS_COMPILE=arm-xilinx-linux-gnueabi-

重新启动机器,再试试 arm-按下tab键会不会自动补全?

然后写一个hello world ,编译放到板子里面运行,ok

交叉编译工具的安装到此结束

 

2uboot的编译

u-boot用来引导linux内核,这个没什么好说的,

不过我遇到过一个问题,机器id不匹配,这不是重点,我竟然没有找到他在哪里传递的参数。。。。。

1下载u-boot源码

https://github.com/Digilent/u-boot-digilent

 

啃爹的是里面没有saveenv这个命令,搞得我每次都要手动输入一次。

u-boot-xlnx-master/include/configs/zynq-commom.h

下面有一些描述zedboard的参数

u-bootinclude/configs/zynq_common.h文件中决定了内核、文件系统和设备树编译后的文件名。如Kernel_image决定了u-boot引导zImage还是uImage

 

make zynq_zed_config

 

make -j4                                                                    (多线程编译更快)

 

mv u-boot u-boot.elf                       (后面制作boot.bin需要)

 

 

至此,u-boot编译结束

 

3NFS内核的编译

我们自己编译内核有那么几个原因,

第一别人的始终不是自己的,自己编译的才是自己的

最重要的是,竟然不支持NFS,不可忍

 

 

下载内核

https://github.com/Digilent/linux-digilent

 

以下引用

http://www.eefocus.com/thinki_cao/blog/13-06/295414_bcd34.html

http://blog.163.com/thinki_cao/blog/static/83944875201439112133825/

非常感谢,如果不合适,请告知谢谢

 

ZEDBoard上出厂的SD卡中自带了一个较完整的linux系统,虽然是精简版,但是对于开发来说已经足够了,在嵌入式linux开发中,挂载NFS协助调试非常常见,但是Digilent给出的内核中并没有开启NFS的支持,具体可以通过/proc/filesystems中有没有nfs相关的内容,执行cat /proc/filesystems | grep nfs,没有找到nfs相关的内容证明内核没有开启对nfs的支持,接下来我们就需要手动配置一下内核,开启nfs支持:(内核源码可以在书的光盘中找到,也可以从github上克隆下来:https://github.com/Digilent/linux-3.3-digilent.git

$ make ARCH=arm digilent_zed_defconfig

 

$ make menuconfig

进入File systems --->NetworkFile Systems --->可以看到默认并没有开启nfs的支持,现在我们开启nfs,相关的选项如下:

 

注意这里我们是要把nfs驱动编译在内核中,所以选择built-in,然后保存配置,不过现在还不能开始编译,如果现在编译根本通不过去,具体原因可能是因为保存的配置又多了额外的很多东西,所以我们只能去找根目录下的.config文件,找到nfs对应的那几行,这里主要是:

CONFIG_NETWORK_FILESYSTEMS=y

CONFIG_NFS_FS=y

CONFIG_NFS_V2=y

CONFIG_NFS_V3=y

# CONFIG_NFS_V3_ACL is not set

# CONFIG_NFS_V4 is not set

# CONFIG_NFS_SWAP is not set

CONFIG_ROOT_NFS=y

# CONFIG_NFSD is not set

CONFIG_LOCKD=y

CONFIG_LOCKD_V4=y

CONFIG_NFS_COMMON=y

CONFIG_SUNRPC=y

# CONFIG_SUNRPC_DEBUG is not set

# CONFIG_CEPH_FS is not set

# CONFIG_CIFS is not set

# CONFIG_NCP_FS is not set

# CONFIG_CODA_FS is not set

# CONFIG_AFS_FS is not set

将上面的内替换到arch/arm/configs/digilent_zed_defconfig中,不过这里先要删除掉

# CONFIG_NETWORK_FILESYSTEMS is not set这一行,并在该位置加上上面的配置内容,这样才能保证内核能够顺利编译通过

接下来执行:

$ make ARCH=arm digilent_zed_defconfig

$ make ARCH=arm

 

编译通过之后,内核即arch/arm/boot目录下的zImage,使用新内核启动以后,执行cat /proc/filesystems | grep nfs,可以找到nfs的设备,说明开启了nfs的支持,挂载指令:

# mount -t nfs SERVERIP:SERVER_PATHLOCAL_PATH -o proto=tcp -o nolock

对于pc机上开启nfs服务,请参考这篇帖子:

【参赛手记】NFS挂载加速程序开发,请注意,这里pc机是nfs服务的提供者,zedboard上的nfs是客户端,所以是把pc机上的目录挂载到zedboard上的linux文件系统中的目录,

其中:SERVERIP是电脑的ipSERVER_PATH是电脑nfs的提供的挂载路径,LOCAL_PATHzedboard上的linux文件系统中的路径

举个例子来说,比如电脑的ip192.168.1.100提供的挂载路径是/rootfs,我们需要把电脑上的路径挂载到板子上的/mnt目录下,(请确保两者能够ping通)那么可以在usb转串口的终端中输入:

# mount -t nfs 192.168.1.100:/rootfs /mnt-o proto=tcp -o nolock

解挂载的时候输入

# umount /mnt

即可

 

这个时候可以把内核放到sd卡里面试试,是否可以实现nfs挂载

 

如果要实现nfs启动

 

NFS启动:

       nfs启动需要修改启动参数,在以前启动参数都是在U-Boot中以bootargs环境变量的形式传递给内核的,现在由于ZedBoard启用了设备树,所以启动参数都是从设备树中传递给Linux内核,我们先看一下设备树中默认的启动参数:

SD卡启动Linaro

bootargs = "console=ttyPS0,115200root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwaitdevtmpfs.mount=1";

console

       指定控制台的设备以及波特了

root

       指定挂载的根文件系统,这里是/dev/mmcblk0p2,当时在创建linarosd卡镜像时会特别提示需要在SD卡中创建两个分区,第一个分区是FAT文件系统,存放内核,设备树,BOOT.bin等,而第二个就是存放Linaro文件系统了,这里也就是对应的mmcblk0p2设备。

rootfstype

       制定跟文件系统的类型,这里是ext4

rw

       rw参数告诉内核以读写方式加载根文件系统。 ro参数告诉内核以只读方式加载根文件系统,以便进行文件系统完整性检查,比如运行fsck

earlyprintk

       console设备注册前(也就是printk注册之前)提供对打印函数的支持,这个之前就可以使用early_printk()函数来代替printk()函数

rootwait

       让内核等待所有设备都被初始化完成后,再去执行root文件系统的挂载工作。这样可以避免根文件系统驱动初始化成功之前就挂载根文件系统。详细的说明可以参考http://blog.csdn.net/liujixin8/article/details/5704991

devtmpfs.mount

       是否挂载devtmpfs1是挂载,0是不挂载。Devtmpfs lets the kernel create a tmpfs very early at kernelinitialization, before any driver core device is registered. Every device witha major/minor will have a device node created in this tmpfs instance. After therootfs is mounted by the kernel, the populated tmpfs is mounted at /dev. Ininitramfs, it can be moved to the manually mounted root filesystem before/sbin/init is executed.相关的信息自己Google去吧。

 

Tftp启动

设置serverip

Setenv serverip 192.168.1.11(电脑的ip,建立tftp服务器,win下可以用tftpd32

 

run jtagboot

其他命令可以查看printenv

 

顺便记录一下uImagezImage的区别

vmlinux是内核文件,zImage是一般情况下默认的压缩内核映像文件,压缩vmlinux,加上一段解压启动代码得到。而uImageu-boot使用bootm命令引导的Linux压缩内核映像文件格式,是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得。它是uboot专用的映像文件,它是在zImage之前加上一个长度为 64字节的,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。

由于bootloader一般要占用0X0地址,所以,uImage相比zImage的好处就是可以和bootloader共存。

其实就是一个自动跟手动的区别,有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需要自己手动去搞那些参数。

如何生成uImage文件?首先uboot/tools目录下寻找mkimage文件,把其copy到系统/usr/local/bin目录下,这样就完成制作工具。然后在内核目录下运行make uImage,如果成功,便可以在arch/arm/boot/目录下发现uImage文件,其大小比zImage64个字节。

此外,平时调试用uImage,不用去管调整了哪些东西;zImage则是一切OK后直接烧0X0。开机就运行。

 

uImage头部信息

 

使用UE打开uImage格式的内核文件,第二行倒数4个字节为05 02 02 00

查看结构体image_header得到,分别为Operating SystemCPU architectureImage TypeCompression Type,对比宏定义,发现操作系统为IH_OS_LINUX(05)、架构为IH_ARCH_ARM(02)、映像类型为IH_TYPE_KERNEL(02)、无压缩。

 

zImage

zedboard 配置一个带NFS文件系统的内核和开机自动挂载sd卡_第1张图片

uImage

zedboard 配置一个带NFS文件系统的内核和开机自动挂载sd卡_第2张图片

以上可以明显的看出头64字节为头部

zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。

根文件系统的制作和修改

官方有提供一个8M的文件系统,基本的命令都有了,但是有时候想要对他进行更改,比如加入某些库文件或者,开机时自动启动某些程序和挂载sd卡,那么可以这么做

 

1解压镜像

gunzip ramdisk.image.gz

2挂载镜像

chmod u+rwx ramdisk.image

mkdir tmp_mnt/

sudo mount -o loop ramdisk.image tmp_mnt/

cd tmp_mnt/

3,这里就可以对他干嘛干嘛了,比如让开机自动挂载sd

cd etc/init.d/

sudo vi rcS

在最后添加上

Mount /devmmcblk0p1 /mnt

保存退出wq

4取消挂载并重新压缩

sudo umount tmp_mnt/

gzip ramdisk.image

 

 

如果要建立一个镜像,可以这么做

 

To create an initrd fromscratch, tools such as Buildroot or Yocto may be used to populate thefilesystem (with BusyBox, tools, etc.).
Alternatively, an empty initrd may be createdand then populated with the desired filesystem contents as specified above. Tocreate an empty (8MB) initrd:

dd if=/dev/zero of=ramdisk.image bs=1024 count=8192

mke2fs -F ramdisk.image -L "ramdisk" -b 1024 -m0

tune2fs ramdisk.image -i 0

chmod a+rwx ramdisk.image

 

如果是initramfs

 

Initramfs

To modify an initramfs:
1. Extract the contents of the cpio.gz archive.

mkdir tmp_mnt/
gunzip -c initramfs.cpio.gz | sudo sh -c 'cd tmp_mnt/ && cpio -i'
cd tmp_mnt/
 

2. Make changes to the filesystem.
3. Repack the filesystem into a cpio.gz archive.

sh -c 'cd tmp_mnt/ && sudo find . | sudo cpio -H newc -o' | gzip -9 > new_initramfs.cpio.gz
 


To create an initramfs from scratch, tools suchas Buildroot or Yocto may be used to populate the filesystem (with BusyBox,tools, etc.).
Alternatively, initramfs image may be created bypopulating a directory with the desired filesystem contents and packing thesecontents into a cpio.gz archive as mentioned above.

把这个考的sd卡中,试试有没有自动挂载

 

6qt的编译

我们在zedboard上使用linux平台,怎么少的了界面呢?界面可以选用qtgtk

不过gtk看起来就很庞大,没什么必要吧,而且qt用的也比较广泛

 

根据官网来制作,值得注意到是,我用官网的4.7版本编译不过换了4.8.6就可以了,如果编译4.7版本遇到问题可以试试换一个版本。

 

  1. /etc/profile下加上几句话

export ZYNQ_QT_BUILD=/path/to/qt/build 

export ZYNQ_QT_INSTALL=/path/to/qt/install

export PATH=$ZYNQ_QT_INSTALL/bin:$PATH

注意上面的应该是自己的安装路径

 

  1. 解压源码

cp qt_build_src.tar $ZYNQ_QT_BUILD

cd $ZYNQ_QT_BUILD

tar xfv qt_build_src.tar

其中

  • qt-everywhere-opensource-src-4.7.3.tar.gz – Qt source archive

  • qmake.conf – Qt qmake configuration file

  • qwt-6.0.1.tar.bz2 – Qwt source archive

  • qwtconfig.pri – Qwt qmake project include file

 

  1. 交叉编译

cp $ZYNQ_QT_BUILD/qmake.confmkspecs/qws/linux-arm-gnueabi-g++

 

./configure \

      -embeddedarm \

      -xplatformqws/linux-arm-gnueabi-g++ \

      -little-endian \

      -opensource\

      -host-little-endian \

      -confirm-license \

      -nomakedemos \

      -nomakeexamples \

      -prefix$ZYNQ_QT_INSTALL

Make

su -         #ifyou need root access to be able to install

make install

 

  1. 编译Qwt – QtWidgets

cd $ZYNQ_QT_BUILD

tar xjfv qwt-6.0.1.tar.bz2

cd qwt-6.0.1

cp $ZYNQ_QT_BUILD/qwtconfig.pri .

qmake qwt.pro

make

su -         #ifyou need root access to be able to install

make install

 

 

  1. 把运行库加入lib为制作镜像做准备

cp -P/path/to/cross/compiler/arm-xilinx-linux-gnueabi/libc/usr/lib/libstdc++.so* \

           $ZYNQ_QT_INSTALL/lib

由于文件系统镜像只有8M,不可能把链接库放到目录下,所以我们需要制作一个镜像,以便挂载

6、制作镜像

cd $ZYNQ_QT_BUILD

 dd if=/dev/zeroof=qt_lib.img bs=1M count=80

 mkfs.ext3 -Fqt_lib.img

su -                           #if you need rootaccess to be able to install

 chmod go+w qt_lib.img

 mount qt_lib.img-o loop /mnt

 cp -rf$ZYNQ_QT_INSTALL/* /mnt

 chmod go-wqt_lib.img

 umount /mnt

 

到这里qt的库编译结束了,能不能用,得找一个程序试试

主机上安装qt

到这个页面

http://download.qt.io/archive/qt/

下载你所要安装的版本

双击就安装好了,好简单 0.0

 

建立一个qt工程,在电脑上线运行试试,目前还没有建立交叉编译工具的路径,

所以先拷贝一份命名为zedboard

然后

qmake –project

qmake

make

应该会生成一个zedboard二进制elf文件

拷贝到sd

 

前面已经安装好了带NFS内核,那么可以直接挂载主机的目录,把文件放大目录中,zedboard就可以读取了

 

qt_lib.img也放入,

挂载到一个与主机相同路径的目录

比如主机的qt交叉编译库安装在/opt/install

那么呀挂载到开发板的这个目录下

然后执行./zedboard –qws

画面出来喽

7opencv的编译安装

待续。。。。。

 

总结

虽然做的工作就那么一点,但是都是在各种错误中走过来的,有喜悦也很累。把它记录一下,希望以后自己忘记的时候回来可以看到,要是能帮到别人就更好了。



你可能感兴趣的:(zedboard)