最近花了几天时间完成了zynqMP 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, ®);
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("mod