SDK 2018.3 支持烧写没有DDR的单板的Flash。
但是SDK 2018.3烧写Flash需要一个FSBL。缺省的FSBL,发现没有定义DDR基地址,会直接退出,导致devcfg、QSPI等模块没有初始化,从而导致烧写Flash失败。
错误信息如下。
cmd /C program_flash -f \
C:\prj\mzed_ddrless.sdk\Application\bootimage\BOOT.bin \
-offset 0 -flash_type qspi_single -fsbl \
C:\prj\mzed_ddrless.sdk\fsbl_ddrless_not_xip\Debug\fsbl_ddrless_not_xip.elf \
-blank_check -verify -cable type xilinx_tcf url TCP:127.0.0.1:3121
****** Xilinx Program Flash
****** Program Flash v2018.2 (64-bit)
**** SW Build 2258646 on Thu Jun 14 20:03:12 MDT 2018
** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
Connected to hw_server @ TCP:127.0.0.1:3121
Available targets and devices:
Target 0 : jsn1
Target 1 : jsn-DLC10-000016c46e9801
Device 0: jsn-DLC10-000016c46e9801-4ba00477-0
Retrieving Flash info...
Initialization done, programming the memory
===== mrd->addr=0xF800025C, data=0x00000000 =====
BOOT_MODE REG = 0x00000000
Downloading FSBL...
Running FSBL...
Finished running FSBL.
===== mrd->addr=0xF8000110, data=0x000FA220 =====
READ: ARM_PLL_CFG (0xF8000110) = 0x000FA220
===== mrd->addr=0xF8000100, data=0x00028008 =====
READ: ARM_PLL_CTRL (0xF8000100) = 0x00028008
===== mrd->addr=0xF8000120, data=0x1F000200 =====
READ: ARM_CLK_CTRL (0xF8000120) = 0x1F000200
===== mrd->addr=0xF8000118, data=0x001452C0 =====
READ: IO_PLL_CFG (0xF8000118) = 0x001452C0
===== mrd->addr=0xF8000108, data=0x0001E008 =====
READ: IO_PLL_CTRL (0xF8000108) = 0x0001E008
Info: Remapping 256KB of on-chip-memory RAM memory to 0xFFFC0000.
===== mrd->addr=0xF8000008, data=0x00000000 =====
===== mwr->addr=0xF8000008, data=0x0000DF0D =====
MASKWRITE: addr=0xF8000008, mask=0x0000FFFF, newData=0x0000DF0D
===== mwr->addr=0xF8000910, data=0x000001FF =====
===== mrd->addr=0xF8000004, data=0x00000000 =====
===== mwr->addr=0xF8000004, data=0x0000767B =====
MASKWRITE: addr=0xF8000004, mask=0x0000FFFF, newData=0x0000767B
Problem in running uboot
Flash programming initialization failed.
ERROR: Flash Operation Failed
执行下列步骤,可以实现烧写没有DDR的单板的Flash。
1. 为了便于调试,建议在工程设置中,或者在文件fsbl_debug.h中,定义宏FSBL_DEBUG_INFO。
2. 确保工程中没有定义XPAR_PS7_DDR_0_S_AXI_BASEADDR。如果有定义,可以在fsbl.h中添加下列行,去掉XPAR_PS7_DDR_0_S_AXI_BASEADDR的定义。示例如下:
#undef XPAR_PS7_DDR_0_S_AXI_BASEADDR
3. 将ps7_init.c从hardware platform工程,复制到FSBL工程;再屏蔽其中的DDR初始化代码。示例如下:
// DDR init
//ret = ps7_config (ps7_ddr_init_data);
//if (ret != PS7_INIT_SUCCESS) return ret;
4. 修改FSBL的main.c,使其在没有DDR基地址情况下,只是不执行DDR相关操作,继续初始化devcfg、QSPI等模块。使用这种FSBL,烧写Flash成功。参考代码如下:
int main(void)
{
u32 BootModeRegister = 0;
u32 HandoffAddress = 0;
u32 Status = XST_SUCCESS;
u32 RegVal;
/*
* PCW initialization for MIO,PLL,CLK and DDR
*/
Status = ps7_init();
if (Status != FSBL_PS7_INIT_SUCCESS) {
fsbl_printf(DEBUG_GENERAL,"PS7_INIT_FAIL : %s\r\n",
getPS7MessageInfo(Status));
OutputStatus(PS7_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
}
/*
* Unlock SLCR for SLCR register write
*/
SlcrUnlock();
/* If Performance measurement is required
* then read the Global Timer value , Please note that the
* time taken for mio, clock and ddr initialisation
* done in the ps7_init function is not accounted in the FSBL
*
*/
#ifdef FSBL_PERF
XTime tCur = 0;
FsblGetGlobalTime(&tCur);
#endif
/*
* Flush the Caches
*/
Xil_DCacheFlush();
/*
* Disable Data Cache
*/
Xil_DCacheDisable();
/*
* Register the Exception handlers
*/
RegisterHandlers();
/*
* Print the FSBL Banner
*/
fsbl_printf(DEBUG_GENERAL,"\n\rXilinx First Stage Boot Loader \n\r");
fsbl_printf(DEBUG_GENERAL,"Release %d.%d %s-%s\r\n",
SDK_RELEASE_YEAR, SDK_RELEASE_QUARTER,
__DATE__,__TIME__);
#ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR
/*
* DDR Read/write test
*/
Status = DDRInitCheck();
if (Status == XST_FAILURE) {
fsbl_printf(DEBUG_GENERAL,"DDR_INIT_FAIL \r\n");
/* Error Handling here */
OutputStatus(DDR_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
}
#endif // XPAR_PS7_DDR_0_S_AXI_BASEADDR
/*
* PCAP initialization
*/
Status = InitPcap();
if (Status == XST_FAILURE) {
fsbl_printf(DEBUG_GENERAL,"PCAP_INIT_FAIL \n\r");
OutputStatus(PCAP_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
}
fsbl_printf(DEBUG_INFO,"Devcfg driver initialized \r\n");
/*
* Get the Silicon Version
*/
GetSiliconVersion();
#ifdef XPAR_XWDTPS_0_BASEADDR
/*
* Check if WDT Reset has occurred or not
*/
CheckWDTReset();
/*
* Initialize the Watchdog Timer so that it is ready to use
*/
Status = InitWatchDog();
if (Status == XST_FAILURE) {
fsbl_printf(DEBUG_GENERAL,"WATCHDOG_INIT_FAIL \n\r");
OutputStatus(WDT_INIT_FAIL);
FsblFallback();
}
fsbl_printf(DEBUG_INFO,"Watchdog driver initialized \r\n");
#endif
/*
* Get PCAP controller settings
*/
PcapCtrlRegVal = XDcfg_GetControlRegister(DcfgInstPtr);
/*
* Check for AES source key
*/
if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) {
/*
* For E-Fuse AES encryption Watch dog Timer disabled and
* User not allowed to do system reset
*/
#ifdef XPAR_XWDTPS_0_BASEADDR
fsbl_printf(DEBUG_INFO,"Watchdog Timer Disabled\r\n");
XWdtPs_Stop(&Watchdog);
#endif
fsbl_printf(DEBUG_INFO,"User not allowed to do "
"any system resets\r\n");
}
/*
* Store FSBL run state in Reboot Status Register
*/
MarkFSBLIn();
/*
* Read bootmode register
*/
BootModeRegister = Xil_In32(BOOT_MODE_REG);
BootModeRegister &= BOOT_MODES_MASK;
/*
* QSPI BOOT MODE
*/
#ifdef XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR
#ifdef MMC_SUPPORT
/*
* To support MMC boot
* QSPI boot mode detection ignored
*/
if (BootModeRegister == QSPI_MODE) {
BootModeRegister = MMC_MODE;
}
#endif
if (BootModeRegister == QSPI_MODE) {
fsbl_printf(DEBUG_GENERAL,"Boot mode is QSPI\n\r");
InitQspi();
MoveImage = QspiAccess;
fsbl_printf(DEBUG_INFO,"QSPI Init Done \r\n");
} else
#endif // XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR
/*
* NAND BOOT MODE
*/
#ifdef XPAR_PS7_NAND_0_BASEADDR
if (BootModeRegister == NAND_FLASH_MODE) {
/*
* Boot ROM always initialize the nand at lower speed
* This is the chance to put it to an optimum speed for your nand
* device
*/
fsbl_printf(DEBUG_GENERAL,"Boot mode is NAND\n");
Status = InitNand();
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_GENERAL,"NAND_INIT_FAIL \r\n");
/*
* Error Handling here
*/
OutputStatus(NAND_INIT_FAIL);
FsblFallback();
}
MoveImage = NandAccess;
fsbl_printf(DEBUG_INFO,"NAND Init Done \r\n");
} else
#endif
/*
* NOR BOOT MODE
*/
if (BootModeRegister == NOR_FLASH_MODE) {
fsbl_printf(DEBUG_GENERAL,"Boot mode is NOR\n\r");
/*
* Boot ROM always initialize the nor at lower speed
* This is the chance to put it to an optimum speed for your nor
* device
*/
InitNor();
fsbl_printf(DEBUG_INFO,"NOR Init Done \r\n");
MoveImage = NorAccess;
} else
/*
* SD BOOT MODE
*/
#if defined(XPAR_PS7_SD_0_S_AXI_BASEADDR) || defined(XPAR_XSDPS_0_BASEADDR)
if (BootModeRegister == SD_MODE) {
fsbl_printf(DEBUG_GENERAL,"Boot mode is SD\r\n");
/*
* SD initialization returns file open error or success
*/
Status = InitSD("BOOT.BIN");
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_GENERAL,"SD_INIT_FAIL\r\n");
OutputStatus(SD_INIT_FAIL);
FsblFallback();
}
MoveImage = SDAccess;
fsbl_printf(DEBUG_INFO,"SD Init Done \r\n");
} else
if (BootModeRegister == MMC_MODE) {
fsbl_printf(DEBUG_GENERAL,"Booting Device is MMC\r\n");
/*
* MMC initialization returns file open error or success
*/
Status = InitSD("BOOT.BIN");
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_GENERAL,"MMC_INIT_FAIL\r\n");
OutputStatus(SD_INIT_FAIL);
FsblFallback();
}
MoveImage = SDAccess;
fsbl_printf(DEBUG_INFO,"MMC Init Done \r\n");
} else
#endif // defined(XPAR_PS7_SD_0_S_AXI_BASEADDR) || defined(XPAR_XSDPS_0_BASEADDR)
/*
* JTAG BOOT MODE
*/
if (BootModeRegister == JTAG_MODE) {
fsbl_printf(DEBUG_GENERAL,"Boot mode is JTAG\r\n");
RegVal = Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_STS_OFFSET);
/** If bitstream was loaded in jtag boot mode prior to running FSBL */
if(RegVal & XDCFG_IXR_PCFG_DONE_MASK)
{
#ifdef PS7_POST_CONFIG
ps7_post_config();
/*
* Unlock SLCR for SLCR register write
*/
SlcrUnlock();
#endif
}
/*
* Stop the Watchdog before JTAG handoff
*/
#ifdef XPAR_XWDTPS_0_BASEADDR
XWdtPs_Stop(&Watchdog);
#endif
/*
* Clear our mark in reboot status register
*/
ClearFSBLIn();
/*
* SLCR lock
*/
SlcrLock();
FsblHandoffJtagExit();
} else {
fsbl_printf(DEBUG_GENERAL,"ILLEGAL_BOOT_MODE \r\n");
OutputStatus(ILLEGAL_BOOT_MODE);
/*
* fallback starts, no return
*/
FsblFallback();
}
fsbl_printf(DEBUG_INFO,"Flash Base Address: 0x%08lx\r\n", FlashReadBaseAddress);
/*
* Check for valid flash address
*/
if ((FlashReadBaseAddress != XPS_QSPI_LINEAR_BASEADDR) &&
(FlashReadBaseAddress != XPS_NAND_BASEADDR) &&
(FlashReadBaseAddress != XPS_NOR_BASEADDR) &&
(FlashReadBaseAddress != XPS_SDIO0_BASEADDR)) {
fsbl_printf(DEBUG_GENERAL,"INVALID_FLASH_ADDRESS \r\n");
OutputStatus(INVALID_FLASH_ADDRESS);
FsblFallback();
}
/*
* NOR and QSPI (parallel) are linear boot devices
*/
if ((FlashReadBaseAddress == XPS_NOR_BASEADDR)) {
fsbl_printf(DEBUG_INFO, "Linear Boot Device\r\n");
LinearBootDeviceFlag = 1;
}
#ifdef XPAR_XWDTPS_0_BASEADDR
/*
* Prevent WDT reset
*/
XWdtPs_RestartWdt(&Watchdog);
#endif
#ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR
/*
* This used only in case of E-Fuse encryption
* For image search
*/
SystemInitFlag = 1;
/*
* Load boot image
*/
HandoffAddress = LoadBootImage();
fsbl_printf(DEBUG_INFO,"Handoff Address: 0x%08lx\r\n",HandoffAddress);
/*
* For Performance measurement
*/
#ifdef FSBL_PERF
XTime tEnd = 0;
fsbl_printf(DEBUG_GENERAL,"Total Execution time is ");
FsblMeasurePerfTime(tCur,tEnd);
#endif
/*
* FSBL handoff to valid handoff address or
* exit in JTAG
*/
FsblHandoff(HandoffAddress);
#else
OutputStatus(NO_DDR);
FsblFallback();
#endif
return Status;
}