Boot minos on the real Zynq-7020 PS (Cortex-A9) without Vivado, an FSBL,
a bitstream, or DDR init — loaded straight into on-chip RAM over JTAG.
- link-zynq-ocm.ld: link the ARM build into OCM (0x0, 192 KiB), which is
alive from reset, so no FSBL/ps7_init and no DDR are needed.
- zynq/openocd-zynq.cfg: OpenOCD config for the on-board FT2232H. Its
EEPROM reports a generic 0403:6010 ("Adapt Device"), which Xilinx
hw_server refuses to auto-detect but OpenOCD drives directly; it sees
the full chain (PL boundary-scan 0x23727093 + ARM DAP 0x4ba00477).
- Makefile: 'zynq' builds the OCM ELF; 'run-zynq' halts A9 core0, loads
the image, and resumes.
The one non-obvious step: the on-board boot firmware leaves the core with
MMU + D-cache + I-cache enabled, which shadow the freshly loaded OCM and
make a plain resume run nothing. run-zynq clears SCTLR to 0x08C54C78 and
forces SVC mode before resuming. Halting (not resetting) keeps the
firmware's PS clock setup so the UART stays live.
Verified on hardware: banner once, then live keystroke echo over the
UART console (ttyUSB1 @115200). Same shared C core now boots on real
RISC-V (D1) and real ARM (Zynq) silicon, plus QEMU x86/riscv/arm.
40 lines
1.1 KiB
Text
40 lines
1.1 KiB
Text
/* link-zynq-ocm.ld (ARM, Zynq-7000 real hardware via JTAG) —
|
|
*
|
|
* On real Zynq the external DDR is NOT usable until an FSBL/ps7_init runs.
|
|
* The on-chip RAM (OCM), however, is alive from reset: 192 KiB mapped at
|
|
* 0x00000000..0x0002FFFF. We link minos entirely into that low OCM so it
|
|
* can be loaded straight over JTAG (OpenOCD) with no FSBL and no DDR init.
|
|
*
|
|
* We keep the PS clocks that the on-board boot firmware already configured
|
|
* by HALTing the A9 (not resetting the whole PS) before loading, so the
|
|
* UART remains clocked. QEMU still uses link.ld (DDR at 0x00100000). */
|
|
OUTPUT_FORMAT(elf32-littlearm)
|
|
ENTRY(_start)
|
|
|
|
MEMORY
|
|
{
|
|
OCM (rwx) : ORIGIN = 0x00000000, LENGTH = 192K
|
|
}
|
|
|
|
SECTIONS
|
|
{
|
|
. = 0x00000000;
|
|
|
|
.text : {
|
|
KEEP(*(.text.boot)) /* _start must be first */
|
|
*(.text .text.*)
|
|
} > OCM
|
|
|
|
.rodata : { *(.rodata .rodata.*) } > OCM
|
|
.data : { *(.data .data.*) } > OCM
|
|
|
|
. = ALIGN(8);
|
|
__bss_start = .;
|
|
.bss : { *(.bss .bss.*) *(COMMON) } > OCM
|
|
. = ALIGN(8);
|
|
__bss_end = .;
|
|
|
|
. = ALIGN(16);
|
|
. += 0x4000; /* 16 KiB boot stack */
|
|
_stack_top = .;
|
|
}
|