最近花了几天时间完成了zynqMP linux的移植工作,这里记录一下工作的流程。

  • zynqMP linux 启动过程
  • U-BOOT制作
  • ATF编译
  • BOOTBIN制作
  • LINUX编译

zynqMP linux 启动过程

下图时xilinx手册上摘录的图,描述了zynqMP 上的linux的整个boot过程

  系统复位后,首先PMU(Platform Management Unit)会执行PMU ROM中固化代码,执行完后会启动CSU处理核,CSU会负责从启动存储介质中加载FSBL(First Stage Boot Loader)至on-chip ram中,FSBL可以由RPU负责执行也可由APU负责执行,须在制作FSBL时确定。继而,CSU激励RPU或APU执行FSBL。FSBL会加载PMU Frameware交付PMU执行。继而FSBL执行完成后切换至ATF(Arm Trusted Frame),ATF于APU上执行。然后ATF启动u-boot,u-boot为linux配置好运行环境将执行权交付给Linux内核。


U-BOOT制作

从xilinx wiki上下载u-boot-xlnx
查看 board/xilinx/zynqmp/zynqmp.c 中board_late_init

int board_late_init(void)
{u32 ver, reg = 0;u8 bootmode;const char *mode;char *new_targets;int ret;if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {debug("Saved variables - Skipping\n");return 0;}ver = zynqmp_get_silicon_version();switch (ver) {case ZYNQMP_CSU_VERSION_VELOCE:setenv("setup", "setenv baudrate 4800 && setenv bootcmd run veloce");case ZYNQMP_CSU_VERSION_EP108:case ZYNQMP_CSU_VERSION_SILICON:setenv("setup", "setenv partid auto");break;case ZYNQMP_CSU_VERSION_QEMU:default:setenv("setup", "setenv partid 0");}ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, &reg);if (ret)return -EINVAL;if (reg >> BOOT_MODE_ALT_SHIFT)reg >>= BOOT_MODE_ALT_SHIFT;bootmode = reg & BOOT_MODES_MASK;puts("Bootmode: ");switch (bootmode) {case USB_MODE:puts("USB_MODE\n");mode = "usb";setenv("modeboot", "usb_dfu_spl");break;case JTAG_MODE:puts("JTAG_MODE\n");mode = "pxe dhcp";setenv("modeboot", "jtagboot");break;case QSPI_MODE_24BIT:case QSPI_MODE_32BIT:mode = "qspi0";puts("QSPI_MODE\n");setenv("modeboot", "qspiboot");break;case EMMC_MODE:puts("EMMC_MODE\n");mode = "mmc0";setenv("modeboot", "emmcboot");break;case SD_MODE:puts("SD_MODE\n");mode = "mmc0";setenv("modeboot", "sdboot");break;case SD1_LSHFT_MODE:puts("LVL_SHFT_");/* fall through */case SD_MODE1:puts("SD_MODE1\n");
#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1)mode = "mmc1";setenv("sdbootdev", "1");
#elsemode = "mmc0";
#endifsetenv("modeboot", "sdboot");printf("modeboot:%s\n","sdboot");break;case NAND_MODE:puts("NAND_MODE\n");mode = "nand0";setenv("modeboot", "nandboot");break;default:mode = "";printf("Invalid Boot Mode:0x%x\n", bootmode);break;}/** One terminating char + one byte for space between mode* and default boot_targets*/new_targets = calloc(1, strlen(mode) +strlen(getenv("boot_targets")) + 2);sprintf(new_targets, "%s %s", mode, getenv("boot_targets"));setenv("boot_targets", new_targets);return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101

这里检查了zynqMP的启动方式,并设置了环境参数 modeboot ,此次测试使用sd卡boot,故modeboot 会被设置为sdboot,故u-boot会执行run sdboot命令,其中sdboot 环境参数设置在include/configs/xilinx_zynqmp.h中定义,如下所示

/* Initial environment variables */
#ifndef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \"kernel_addr=0x80000\0" \"initrd_addr=0xa00000\0" \"initrd_size=0x2000000\0" \"fdt_addr=4000000\0" \"fdt_high=0x10000000\0" \"loadbootenv_addr=0x100000\0" \"sdbootdev=0\0"\"kernel_offset=0x180000\0" \"fdt_offset=0x100000\0" \"kernel_size=0x1e00000\0" \"fdt_size=0x80000\0" \"bootenv=uEnv.txt\0" \"serverip=192.168.1.18\0" \"bootargs=earlycon clk_ignore_unused\0" \"loadbootenv=load mmc $sdbootdev:$partid ${loadbootenv_addr} ${bootenv}\0" \"importbootenv=echo Importing environment from SD ...; " \"env import -t ${loadbootenv_addr} $filesize\0" \"sd_uEnvtxt_existence_test=test -e mmc $sdbootdev:$partid /uEnv.txt\0" \"sata_root=if test $scsidevs -gt 0; then setenv bootargs $bootargs root=/dev/sda rw rootfstype=ext4; fi\0" \"sataboot=load scsi 0 80000 boot/Image && load scsi 0 $fdt_addr boot/system.dtb && booti 80000 - $fdt_addr\0" \"veloce=fdt addr f000000 && fdt resize" \"fdt set /amba/misc_clk clock-frequency <48000> && "\"fdt set /timer clock-frequency <240000> && " \"fdt set /amba/i2c_clk clock-frequency <240000> && " \"booti 80000 - f000000\0" \"netboot=tftpboot 10000000 image.ub && bootm\0" \"qspiboot=sf probe 0 0 0 && sf read $fdt_addr $fdt_offset $fdt_size && " \"sf read $kernel_addr $kernel_offset $kernel_size && " \"booti $kernel_addr - $fdt_addr\0" \"uenvboot=" \"if run sd_uEnvtxt_existence_test; then " \"run loadbootenv; " \"echo Loaded environment from ${bootenv}; " \"run importbootenv; " \"fi; " \"if test -n $uenvcmd; then " \"echo Running uenvcmd ...; " \"run uenvcmd; " \"fi\0" \"sdboot=mmc dev $sdbootdev && mmcinfo && run uenvboot;" \"setenv ipaddr   192.168.1.15 ;" \"setenv serverip 192.168.1.18 ;" \"setenv netmask 255.255.255.0 ;" \"ping $serverip ;" \"setenv bootargs console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.1.18:/home/rootfs,tcp ip=dhcp rw earlyprintk rootwait ;" \"tftpboot $kernel_addr Image &&" \"tftpboot $fdt_addr system.dtb &&" \"booti $kernel_addr - $fdt_addr\0" \"emmcboot=run sdboot\0" \"nandboot=nand info && nand read $fdt_addr $fdt_offset $fdt_size && " \"nand read $kernel_addr $kernel_offset $kernel_size && " \"booti $kernel_addr - $fdt_addr\0" \"xen_prepare_dt=fdt addr $fdt_addr && fdt resize 128 && " \"fdt set /chosen \\\\#address-cells <1> && " \"fdt set /chosen \\\\#size-cells <1> && " \"fdt mknod /chosen dom0 && " \"fdt set /chosen/dom0 compatible \"xen,linux-zimage\" \"xen,multiboot-module\" && " \"fdt set /chosen/dom0 reg <0x80000 0x$filesize> && " \"fdt set /chosen xen,xen-bootargs \"console=dtuart dtuart=serial0 dom0_mem=768M bootscrub=0 maxcpus=1 timer_slop=0\" && " \"fdt set /chosen xen,dom0-bootargs \"console=hvc0 earlycon=xen earlyprintk=xen maxcpus=1 clk_ignore_unused\"\0" \"xen_prepare_dt_qemu=run xen_prepare_dt && " \"fdt set /cpus/cpu@1 device_type \"none\" && " \"fdt set /cpus/cpu@2 device_type \"none\" && " \"fdt set /cpus/cpu@3 device_type \"none\" && " \"fdt rm /cpus/cpu@1 compatible && " \"fdt rm /cpus/cpu@2 compatible && " \"fdt rm /cpus/cpu@3 compatible\0" \"xen=tftpb $fdt_addr system.dtb &&  tftpb 0x80000 Image &&" \"run xen_prepare_dt && " \"tftpb 6000000 xen.ub && tftpb 0x1000000 image.ub && " \"bootm 6000000 0x1000000 $fdt_addr\0" \"xen_qemu=tftpb $fdt_addr system.dtb && tftpb 0x80000 Image && " \"run xen_prepare_dt_qemu && " \"tftpb 6000000 xen.ub && tftpb 0x1000000 image.ub && " \"bootm 6000000 0x1000000 $fdt_addr\0" \"jtagboot=tftpboot 80000 Image && tftpboot $fdt_addr system.dtb && " \"tftpboot 6000000 rootfs.cpio.ub && booti 80000 6000000 $fdt_addr\0" \"nosmp=setenv bootargs $bootargs maxcpus=1\0" \"nfsroot=setenv bootargs $bootargs root=/dev/nfs nfsroot=$serverip:/mnt/sata,tcp ip=$ipaddr:$serverip:$serverip:255.255.255.0:zynqmp:eth0:off rw\0" \"sdroot0=setenv bootargs $bootargs root=/dev/mmcblk0p2 rw rootwait\0" \"sdroot1=setenv bootargs $bootargs root=/dev/mmcblk1p2 rw rootwait\0" \"android=setenv bootargs $bootargs init=/init androidboot.selinux=disabled androidboot.hardware=$board\0" \"android_debug=run android && setenv bootargs $bootargs video=DP-1:1024x768@60 drm.debug=0xf\0" \"usb_dfu_spl=booti $kernel_addr - $fdt_addr\0" \"usbhostboot=usb start && load usb 0 $fdt_addr system.dtb && " \"load usb 0 $kernel_addr Image && " \"booti $kernel_addr - $fdt_addr\0" \PARTS_DEFAULT \DFU_ALT_INFO
#endif#define CONFIG_PREBOOT      "run setup"
#define CONFIG_BOOTCOMMAND  "run $modeboot"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

其中sdboot为

    "sdboot=mmc dev $sdbootdev && mmcinfo && run uenvboot;" \"setenv ipaddr   192.168.1.15 ;" \"setenv serverip 192.168.1.18 ;" \"setenv netmask 255.255.255.0 ;" \"ping $serverip ;" \"setenv bootargs console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.1.18:/home/rootfs,tcp ip=dhcp rw earlyprintk rootwait ;" \"tftpboot $kernel_addr Image &&" \"tftpboot $fdt_addr system.dtb &&" \"booti $kernel_addr - $fdt_addr\0" \
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

此处实现了TFTP形式的boot以及nfs文件系统,这里就不解释TFTP Boot及nfs(xilinx默认配置是从sd卡第一分区(FAT格式)读取devicetree以及Image实现boot,并以sd卡第二分区(ext4格式)作为系统的跟文件系统)。

至此可以对u-boot编译

cd $u-boot-xlnx-dir
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make distclean
make xilinx_zynqmp_zcu102_rev1_0_defconfig
make -j4  #-jn 为你要运行的核数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在工程根目录下面生成u-boot.elf


ATF编译

下载Arm-Trusted-Firmware

cd $Arm-Trusted-Firmware
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make PLAT=zynqmp RESET_TO_BL31=1
  • 1
  • 2
  • 3
  • 4

由于一开始用的gcc为apt安装,此版本有bug,
故去linaro官网下载,下载版本为7.2
生成的 ATF在/build/zynqmp/release/bl31


BOOT.BIN制作

使用Xilinx SDK中 Xilinx->Create Boot Image制作BOOT.BIN
bif文件如下所示:

//arch = zynqmp; split = false; format = BIN
the_ROM_image:
{[fsbl_config]a53_x64[bootloader]PROJECT_DIR/project_1.sdk/fsbl/Debug/fsbl.elf[pmufw_image]PROJECT_DIR/project_1.sdk/pmu/Debug/pmu.elf[destination_device = pl]PROJECT_DIR/project_1.sdk/design_1_wrapper_hw_platform_0/design_1_wrapper.bit[destination_cpu = a53-0, exception_level = el-3]PROJECT_DIR/project_1.sdk/bl31.elf[destination_cpu = a53-0, exception_level = el-2]PROJECT_DIR/project_1.sdk/u-boot.elf
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

其中PMU、FSBL由SDK中生成

在编译PMU的时候碰到如下问题

mb-gcc未找到
  • 1

解决办法:

sudo dpkg --add-architecture i386
sudo apt install libstdc++5:i386 
  • 1
  • 2

然后又出现如下问题:

mb-gcc: error while loading shared libraries: libstdc++.so.6: wrong ELF class: ELFCLASS64 
  • 1

解决方法:

sudo apt install gcc-multilib 
  • 1

LINUX编译

下载xilinx linux

cd linux-xlnx
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make xilinx_zynqmp_defconfig
make menuconfig
make -j4  #-jn n为你要运行的核数

zynqMP LINUX 启动流程和移植相关推荐

  1. RISC-V Linux 启动流程分析

    " Author:  通天塔 985400330@qq.com Date:    2022/05/15 Revisor: lzufalcon falcon@tinylab.org Proje ...

  2. 嵌入式linux内核启动过程,嵌入式Linux:ARM Linux启动流程

    ARM Linux启动流程大致为:bootloader---->kernel---->root filesystem.bootloader 是一上电就拿到cpu 的控制权的,而bootlo ...

  3. Linux 进内核,arm linux 启动流程之 进入内核

    原标题:arm linux 启动流程之 进入内核 还是从编译链接生成vm 的过程来看吧,由一大堆.o文件链接而成,第一个就是 kernel/arch//kernel/head-armv.o ,而且我们 ...

  4. Linux 启动流程学习

    Linux 启动流程学习 开机自检(加载BIOS) 无论什么机器,在开机后都要进行通电自检(硬件),如果硬件有问题,则无法继续下去. (例如当内存条松动时或者损坏,就会发出嘀嘀嘀警报声).接着开始加载 ...

  5. linux启动流程及自定义gurb

    linux 启动流程 POST BIOS(boot sequence) 所选择的启动设备次序的MBR中是否有引导程序, ----> MBR(bootloader) 提供内核列表 -------& ...

  6. 全志linux关机键,全志平台linux启动流程分析

    转载:全志平台linux启动流程分析 一.BROM阶段 机器上电之后会执行固化在BROM里面的一段引导程序,这个程序会依次遍历所有支持的启动介质,直到找到第一个支持的.目前支持的启动介质是sd/mmc ...

  7. 【树莓派不吃灰】命令篇⑥ 了解树莓派Boot分区,学习Linux启动流程

    目录 1. Linux启动过程 1.1 内核引导 1.2 运行init初始化进程 -- 初始化系统环境 1.3 运行级别 -- runlevel 1.4 系统初始化 -- 加载开机启动程序 1.5 用 ...

  8. 最详细最易理解的linux启动流程解读及相关问题,万字高能无废话

    linux启动流程 linux的启动流程是运维所必须非常理解的东西,因为它将会是我们在发生服务器开不起机等情况的主要排错手段,充分理解了liunx的启动流程能够助力我们对此类故障的快速定位和处理. 废 ...

  9. 嵌入式 Linux 启动流程和 bootloader 介绍

    目录 嵌入式 Linux 启动流程 简介 启动流程 Bootloader 简介 市面上可见的 bootloader 入式 Linux 启动流程 简介 对于一个 SoC 芯片而言,bootloader ...

  10. EBB-11、Linux启动流程

    一.Linux开机流程 (一)power on 开机后加载BIOS(Basic Input Output System,基本的输入输出系统),BIOS加载 CMOS中所存放的当前主机各项硬件配置.系统 ...

最新文章

  1. 创建试图 失败_导致微服务失败的 11 个原因
  2. PHP - 如何在函数内访问另一个文件中的变量
  3. 排序、翻页、函数计算问题
  4. python三大器_Python - 三大器 迭代器,生层器,装饰器
  5. 成都电子神技大学模拟题(取模运算)
  6. workbench设置单元坐标系_ANSYS经典案例在Workbench中实现分享连载(三)
  7. enable pen pressure in ps
  8. 实战CSS:小米商城静态实现
  9. 百度智能云金融安全计算平台有多强?安排!
  10. win10引导安卓x86_实用教程,教你如何安装Win10+安卓双系统
  11. 项目计划应该怎么样做?看这一篇就够了!
  12. mysql phpwind_PHPWind环境搭建(Linux)
  13. 汇编语言中xor指令_汇编各类指令用法及含义分析 - 全文
  14. php做网站需要注意什么,浅谈新手做网站应该注意的问题
  15. 如何利用PPT制作九宫格图片效果
  16. Bootstrap 下拉菜单(Dropdown)插件
  17. HTTP 请求方法(GET、POST 和 PUT)
  18. ElementUI的Table组件在无数据情况下让“暂无数据”文本居中显示
  19. pd.concat用法
  20. 解读Android LOG机制的实现:(1)LOG的实现架构

热门文章

  1. AMCL代码详解(二)位姿初始化
  2. 关于各种校园网,局域网等出现IP识别错误(169IP开头)及其导致的联网失败,DNS错误的解决方法
  3. 瀚高数据库查询表字段及备注
  4. 【NLP】⚠️学不会打我! 半小时学会基本操作 2⚠️ 关键词
  5. 震惊了!鸿蒙又多了一种开发方式Ets,让更多的人赶上红利!
  6. python 随机产生一个整数 并猜测该数字小游戏
  7. 4. Python基础:Python内置函数详细介绍(全)
  8. 如何在win7下安装XP系统?
  9. 关于telnet逛bbs论坛
  10. 乔治城大学 计算机排名,乔治城大学计算机科学硕士排名第40(2020年TFE Times排名)...