ZYNQ从vitis生成linux系统编译启动文件

一,vivado到vitis流程

ZYNQ MPSoC芯片的特点是,需要fsbl来引导uboot。fsbl全称为First Stage Boot Loader,是用户可以接触到的最早的启动部分。我们使用 vitis 跑裸机代码的时候,fsbl 也发挥作用了,在程序运行前会打印 fsbl 的信息,引导裸机和引导系统都需要 fsbl 文件。

vitis会生成pmufw.elf和system_wrapper.bit这两个文件。pmufw.elf顾名思义就是pmu的管理程序,它负责了板级的电源管理。system_wrapper.bit文件则是PL端的配置文件,通过这个文件我们可以在linux启动时将vivado工程给一并配置至pl端,这样我们就能通过linux与PL端交互了。bit文件不仅会配置pl端,ps端也需要通过bit文件设置,要想让linux系统启动时配置好FPGA 端的逻辑,首先我们得先导出在vivado里设计好的硬件,然后用vitis把它汇编成机器可以识别的bit 文件,最后使用 linux下的工具包将其打包进BOOT.bin文件,也就是uboot。

二,vitis配置流程

1,从vivado2021导入PL端硬件到vitis。生成的硬件文件,以.xsa结尾

2,从桌面打开xilinx vitis 2021中填入路径

ZYNQ从vitis生成linux系统编译启动文件_第1张图片 3,添加好后,开始新建工程,依次展开file – new – platform project:

ZYNQ从vitis生成linux系统编译启动文件_第2张图片

 ZYNQ从vitis生成linux系统编译启动文件_第3张图片

点击Browse找到刚刚生成的xsa文件,再如图设置其他参数,点击finish完成设置

ZYNQ从vitis生成linux系统编译启动文件_第4张图片 在工程上右击选择 Build Project 开始编译

 ZYNQ从vitis生成linux系统编译启动文件_第5张图片

编译完毕,{工程位置}\zu_sdk\zu_base\hw\ 生成system_wrapper.bit。设备树也在里面。

{工程位置}\zu_sdk\zu_base\export\zu_base\sw\zu_base\boot\生成fsbl.elf。

ZYNQ从vitis生成linux系统编译启动文件_第6张图片

把设备树zynqmp-mzux.dts分别复制到lab-xlnx/sources/uboot/arch/arm/dts和lab-xlnx/sources/kernel/arch/arm/boot/dts中,选择覆盖之前里面有的设备树文件。

ZYNQ从vitis生成linux系统编译启动文件_第7张图片

ZYNQ从vitis生成linux系统编译启动文件_第8张图片

 将system_wrapper.bit、fsbl.elf 两个文件分别改名为system.bit、zynq_fsbl.elf,分别复制到/lab-xlnx/boards/mz7x/ubuntu/output/target中,有的话选择覆盖之前的文件。

ZYNQ从vitis生成linux系统编译启动文件_第9张图片

ZYNQ从vitis生成linux系统编译启动文件_第10张图片

 三,虚拟机编译启动文件

1, source配置一些环境变量

 2,编译uboot启动文件,执行make_uboot.sh  

ZYNQ从vitis生成linux系统编译启动文件_第11张图片

# => Setting The Development Environment Variables
if [ ! "${ZN_CONF_DONE}" ];then
  printf "\033[31m[ERROR]\033[0m "
  printf "Please source the settings-.sh script first.\n"
  exit 1
fi

# => Filename of the running script
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => Directory containing the running script
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => Help and information
usage() {
  echo "Purpose: build the u-boot and install the image after building."
  echo "Usage  : ${ZN_SCRIPT_NAME} [option]"
  echo "options:"
  echo "--help: Display this help message"
  exit 0;
}
expr "$*" : ".*--help" > /dev/null && usage

# => The beginning
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}\n"

# => Make sure the source is there
[[ "$(ls -A ${ZN_UBOOT_DIR})" = "" ]] && \
  error_exit "Can't find the source code of u-boot."

# => Building the U-Boot bootloader is a part of the Xilinx design flow.
echo_info "Build U-Boot on the ${ZN_UBOOT_DIR}."
make -C ${ZN_UBOOT_DIR} ${MAKE_JOBS}
if [ $? -eq 0 ]; then
  echo_info "Installing the U-Boot Image."
  cp ${ZN_UBOOT_DIR}/u-boot ${ZN_TARGET_DIR}/u-boot.elf
else
  error_exit "U-Boot - Build Failed"
fi

# => The end
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}\n"

2,编译制作启动内核/驱动make_kernel.sh

ZYNQ从vitis生成linux系统编译启动文件_第12张图片 

# => Setting The Development Environment Variables
if [ ! "${ZN_CONF_DONE}" ];then
  printf "\033[31m[ERROR]\033[0m "
  printf "Please source the configs/.sh script first.\n"
  exit 1
fi

# => Filename of the running script
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => Directory containing the running script
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => Help and information
usage() {
  echo "Purpose: Compiling and Installing Linux kernel, Device Tree and module"
  echo "Usage  : ${ZN_SCRIPT_NAME} [option]"
  echo "options:"
  echo "--help: Display this help message"
  exit 0;
}
expr "$*" : ".*--help" > /dev/null && usage

# => The beginning
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}\n"

# => Make sure the source is there
[[ "$(ls -A ${ZN_KERNEL_DIR})" = "" ]] && \
  error_exit "Can't find the source code of kernel."

# => Make sure the target directory is there
[[ ! "${ZN_TARGET_DIR}" ]] && error_exit "Can't find the target directory."

# => Compiling the Kernel
echo_info "Building the kernel image on the ${ZN_KERNEL_DIR}."
if [ ${ARCH} = arm64 ]; then
  make -C ${ZN_KERNEL_DIR} ${MAKE_JOBS}
else
  make -C ${ZN_KERNEL_DIR} ${MAKE_JOBS} UIMAGE_LOADADDR=0x8000 uImage
fi

if [ $? -eq 0 ]; then
  echo_info "Installing the Kernel Image."
  cp -a ${ZN_KERNEL_IMG} ${ZN_TARGET_DIR}
else
  error_exit "Kernel Image - Build Failed."
fi


# => Compiling the Device Tree Binaries
echo_info "Building the Device Tree Binaries on the ${ZN_KERNEL_DIR}."
case ${ARCH} in
  arm64)
    cp ${ZN_DTB_DIR}/${ZN_DTB_NAME} ${ZN_TARGET_DIR}/system.dtb
    ;;
  arm)
    ${ZN_DTC_DIR}/dtc -I dts -O dtb -o ${ZN_DTB_DIR}/${ZN_DTB_NAME} ${ZN_DTS_DIR}/${ZN_DTS_NAME}
    if [ $? -eq 0 ]; then
      echo_info "The Device Tree - Build OK"
    else
      error_exit "The Device Tree - Build Failed"
    fi
    cp ${ZN_DTB_DIR}/${ZN_DTB_NAME} ${ZN_TARGET_DIR}/devicetree.dtb
    ;;
  *)
    echo_error "Unsupported architecture!" && return 1
esac

# => Compiling the Kernel Modules
echo_info "Building the Kernel Modules on the ${ZN_KERNEL_DIR}"
make -C ${ZN_KERNEL_DIR} ${MAKE_JOBS} modules
if [ $? -eq 0 ]; then
  echo_info "Installing the Kernel Modules"

  ZN_ROOTFS_MOUNT_POINT=${ZN_OUTPUT_DIR}/rootfs
  mkdir -p ${ZN_ROOTFS_MOUNT_POINT}
  trap "sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}" EXIT

  sudo tar zxf ${ZN_TARGET_DIR}/rootfs.tar.gz -C ${ZN_ROOTFS_MOUNT_POINT}
  sudo rm -rf ${ZN_ROOTFS_MOUNT_POINT}/lib/modules/

  sudo make -C ${ZN_KERNEL_DIR} ${MAKE_JOBS} \
    INSTALL_MOD_PATH=${ZN_ROOTFS_MOUNT_POINT} modules_install
  if [ $? -eq 0 ]; then
    sudo rm ${ZN_TARGET_DIR}/rootfs.tar.gz
    sudo tar zcf ${ZN_TARGET_DIR}/rootfs.tar.gz -C ${ZN_ROOTFS_MOUNT_POINT} .
  else
    error_exit "The Kernel Modules - Install Failed"
  fi

else
  error_exit "Kernel Modules - Build Failed"
fi

# => The end
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}\n"

3,生成文件系统镜像:create_image.sh

 ZYNQ从vitis生成linux系统编译启动文件_第13张图片

# => Setting The Development Environment Variables
if [ ! "${ZN_CONF_DONE}" ];then
  printf "\033[31m[ERROR]\033[0m "
  printf "Please source the configs/.sh script first.\n"
  exit 1
fi

# => Filename of the running script
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => Directory containing the running script
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => Help and information
usage() {
  echo "Purpose: Building Debian/Ubuntu Image for SD card"
  echo "Usage  : ${ZN_SCRIPT_NAME} [option]"
  echo "options:"
  echo "--help: Display this help message"
  exit 0;
}
expr "$*" : ".*--help" > /dev/null && usage

# => The beginning
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}\n"

if [ ${ARCH} = arm64 ]; then
  create_zynqmp_image.sh
else
  create_zynq_image.sh
fi

# => The end
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}\n"

 五,SD卡分区和系统启动验证

1,格式化并分区 u 盘,先输入盘符,再输入确认:make_parted.sh

# => Setting The Development Environment Variables
if [ ! "${ZN_CONF_DONE}" ];then
  printf "\033[31m[ERROR]\033[0m "
  printf "Please source the configs/.sh script first.\n"
  exit 1
fi

# => Filename of the running script
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => Directory containing the running script
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => Help and information
usage() {
  echo "Purpose: Repartition SD Card"
  echo "Usage  : ${ZN_SCRIPT_NAME} [option]"
  echo "options:"
  echo "--help: Display this help message"
  exit 0;
}
expr "$*" : ".*--help" > /dev/null && usage

# => The beginning
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}\n"

# => Check for dependencies
if ! type parted > /dev/null 2>&1; then
  echo_info "Installing parted..."
  ${SUDO} apt-get update && ${SUDO} apt-get --assume-yes install parted
  echo_info "Done!"
fi

# 0、 Plug in your SD Card to your Linux machine.

# 1、Determine what device to use
DISKS=($( grep -Hv ^0$ /sys/block/*/removable | sed s/removable:.*$/device\\/uevent/ |
  xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ |
  cut -d / -f 4 ))

for i in "${!DISKS[@]}"; do DISKS[$i]="/dev/${DISKS[$i]}"; done

until [[ -b /dev/${DISK} && ${DISKS[@]/"/dev/${DISK}"/} != ${DISKS[@]} ]]; do
  lsblk -d "${DISKS[@]}" -o NAME,RM,SIZE,TYPE,MODEL,SERIAL
  print_info "Type device filename, or press  to exit: " && read DISK
  [[ -z ${DISK} ]] && exit 0
done

# 2. Remove All Existing Partitions
print_warn "ALL DATA ON ${DISK} WILL BE ERASED!!! DO YOU WANT TO CONTINUE [y/N]? " && read REPLY
case ${REPLY} in
  y|Y)
    echo_info "Umount All Mounted Partitions"
    for part in $(lsblk /dev/${DISK} -o mountpoint --noheadings); do
      ${SUDO} umount ${part}
    done

    echo_info "Remove All Existing Partitions from ${DISK}"
    for PARTITION in $(${SUDO} parted /dev/${DISK} print | awk '/^ /{print $1}'); do
      ${SUDO} parted -s /dev/${DISK} rm ${PARTITION}
    done

    echo_info "Choose the MBR Partitioning Standard"
    ${SUDO} parted -s /dev/${DISK} mklabel msdos

    echo_info "Create the fat32 partition of 100MB and make it bootable"
    ${SUDO} parted -s /dev/${DISK} mkpart primary fat32 0% 100MiB && ${SUDO} parted -s /dev/${DISK} set 1 boot on

    echo_info "Create the ext4 partition until end of device"
    ${SUDO} parted -s /dev/${DISK} mkpart primary ext4 100MiB 100%

    echo_info "Re-read The Partition Table Without Rebooting Linux System"
    ${SUDO} partprobe /dev/${DISK} && sleep 1 && lsblk /dev/${DISK}

    # Create a Filesystem on the New Partition
    for PARTITION in $(lsblk -l /dev/${DISK} | grep part | awk '{print $1}'); do
      PARTNUM=${PARTITION##*[[:alpha:]]}
      case ${PARTNUM} in
        1)
          echo_info "To format a FAT32 filesystem on /dev/${PARTITION} with a 'BOOT' disk label"
          ${SUDO}  mkfs.vfat -F 32 -n "BOOT" /dev/${PARTITION}
          ;;
        2)
          echo_info "To format an ext4 filesystem on /dev/${PARTITION} with a 'rootfs' disk label"
          echo y | ${SUDO} mkfs.ext4 -L rootfs /dev/${PARTITION}
          ;;
        *)
          echo_warn "Extra unintended partition"
          ;;
      esac
    done

    ;;
  *)
    ;;
esac

# => The end
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}\n"

2,烧写启动文件与系统文件,输入盘符:deploy_image.sh

# => Setting The Development Environment Variables
if [ ! "${ZN_CONF_DONE}" ];then
  printf "\033[31m[ERROR]\033[0m "
  printf "Please source the configs/.sh script first.\n"
  exit 1
fi

# => Filename of the running script
ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})"

# => Directory containing the running script
ZN_SCRIPT_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})" && pwd)"

# => Help and information
usage() {
  echo "Purpose: Deploying Debian/Ubuntu Image to SD card"
  echo "Usage  : ${ZN_SCRIPT_NAME} [option]"
  echo "options:"
  echo "--help: Display this help message"
  exit 0;
}
expr "$*" : ".*--help" > /dev/null && usage

# => The beginning
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}\n"

# 0、 Plug in your SD Card to your Linux machine.

# 1、Determine what device to use
DISKS=($( grep -Hv ^0$ /sys/block/*/removable | sed s/removable:.*$/device\\/uevent/ |
  xargs grep -H ^DRIVER=sd | sed s/device.uevent.*$/size/ | xargs grep -Hv ^0$ |
  cut -d / -f 4 ))

for i in "${!DISKS[@]}"; do DISKS[$i]="/dev/${DISKS[$i]}"; done

until [[ -b /dev/${DISK} && ${DISKS[@]/"/dev/${DISK}"/} != ${DISKS[@]} ]]; do
  lsblk -d "${DISKS[@]}" -o NAME,RM,SIZE,TYPE,MODEL,SERIAL
  print_info "Type device filename, or press  to exit: " && read DISK
  [[ -z ${DISK} ]] && exit 0
done

# 2、
echo_info "Umount All Mounted Partitions"
for PART in $(lsblk /dev/${DISK} -o mountpoint --noheadings); do
  ${SUDO} umount ${PART}
done

# 3、
SDCARD_MOUNT_POINT=${ZN_OUTPUT_DIR}/sdcard && mkdir -p ${SDCARD_MOUNT_POINT}
trap "sudo umount ${SDCARD_MOUNT_POINT} &> /dev/null; sudo rm -rf ${SDCARD_MOUNT_POINT}" EXIT

for PARTITION in $(lsblk -l /dev/$DISK | grep part | awk '{print $1}'); do
  PARTNUM=${PARTITION##*[[:alpha:]]}
  case ${PARTNUM} in
    1)
      [[ $(lsblk -no FSTYPE /dev/${PARTITION}) != 'vfat' ]] && \
        error_exit "No bootable device found"

      echo_info "Mount the boot partition to ${SDCARD_MOUNT_POINT}"
      ${SUDO} mount -t vfat /dev/${PARTITION} ${SDCARD_MOUNT_POINT}

      echo_info "Install boot images to ${SDCARD_MOUNT_POINT}"
      ${SUDO} rsync -rv ${ZN_IMAGES_DIR}/boot/ ${SDCARD_MOUNT_POINT} && sync

      echo_info "Umount the boot partition from ${SDCARD_MOUNT_POINT}"
      ${SUDO} umount ${SDCARD_MOUNT_POINT}
      ;;
    2)
      [[ $(lsblk -no FSTYPE /dev/${PARTITION}) != 'ext4' ]] && \
        error_exit "No rootfs partition found"

      echo_info "Mount the rootfs partition to ${SDCARD_MOUNT_POINT}"
      ${SUDO} mount -t ext4 /dev/${PARTITION} ${SDCARD_MOUNT_POINT}

      if [ "$(ls -A ${SDCARD_MOUNT_POINT})" != "lost+found" ]; then
        ${SUDO} umount ${SDCARD_MOUNT_POINT}
        error_exit "The ROOTFS partition is dirty, please clean it!"
      fi

      echo_info "Install rootfs images to ${SDCARD_MOUNT_POINT}"
      ${SUDO} tar zxmf ${ZN_IMAGES_DIR}/rootfs/rootfs.tar.gz -C ${SDCARD_MOUNT_POINT} && sync
      if [ -d "${ZN_IMAGES_DIR}/custom" ];then
        ${SUDO} rsync -av ${ZN_IMAGES_DIR}/custom/ ${SDCARD_MOUNT_POINT} && sync
      fi

      if [ -d "${ZN_IMAGES_DIR}/recovery" ];then
        ${SUDO} rsync -av ${ZN_IMAGES_DIR}/recovery ${SDCARD_MOUNT_POINT} && sync
        ${SUDO} rsync -av ${ZN_IMAGES_DIR}/boot/ ${SDCARD_MOUNT_POINT}/recovery/boot && sync
        ${SUDO} rsync -av ${ZN_IMAGES_DIR}/custom/ ${SDCARD_MOUNT_POINT}/recovery/custom && sync
        ${SUDO} rsync -av ${ZN_IMAGES_DIR}/rootfs/ ${SDCARD_MOUNT_POINT}/recovery/rootfs && sync
      fi

      echo_info "umount the rootfs partition from ${SDCARD_MOUNT_POINT}"
      ${SUDO} umount ${SDCARD_MOUNT_POINT}
      ;;
    *)
      echo_warn "Extra unintended partition"
      ;;
  esac
done

# => The end
print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Finished ${ZN_SCRIPT_NAME}\n"

3,将模式开关拨至SD卡启动模式,再给ZYNQ上电验证

你可能感兴趣的:(linux,fpga开发)