This is a set of snippets to get LiteX to statically build software as part of the gateware build process. The goal is to have only a single SRAM, rather than wasting block RAM on a separate ROM and RAM partition, and to have a small chunk of code loaded in that RAM that is built as part of the gateware build process, but not necessarily the LiteX BIOS.
Last active
May 2, 2024 19:56
-
-
Save jwise/827ee5e26e1cdea7aa636542bf772547 to your computer and use it in GitHub Desktop.
"single stage to orbit" LiteX software
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* gist filenames cannot have / in them, but this is fw/linker.ld */ | |
INCLUDE generated/output_format.ld | |
ENTRY(_start) | |
__DYNAMIC = 0; | |
INCLUDE generated/regions.ld | |
SECTIONS | |
{ | |
.text : | |
{ | |
_ftext = .; | |
/* Make sure crt0 files come first, and they, and the isr */ | |
/* don't get disposed of by greedy optimisation */ | |
*crt0*(.text) | |
KEEP(*crt0*(.text)) | |
KEEP(*(.text.isr)) | |
*(.text .stub .text.* .gnu.linkonce.t.*) | |
_etext = .; | |
} > main_ram | |
.rodata : | |
{ | |
. = ALIGN(8); | |
_frodata = .; | |
*(.rodata .rodata.* .gnu.linkonce.r.*) | |
*(.rodata1) | |
*(.got .got.*) | |
*(.toc .toc.*) | |
. = ALIGN(8); | |
_erodata = .; | |
} > main_ram | |
.data : | |
{ | |
. = ALIGN(8); | |
_fdata = .; | |
_fdata_rom = .; | |
*(.data .data.* .gnu.linkonce.d.*) | |
*(.data1) | |
_gp = ALIGN(16); | |
*(.sdata .sdata.* .gnu.linkonce.s.*) | |
. = ALIGN(8); | |
_edata = .; | |
_edata_rom = .; | |
} > main_ram | |
.bss : | |
{ | |
. = ALIGN(8); | |
_fbss = .; | |
*(.dynsbss) | |
*(.sbss .sbss.* .gnu.linkonce.sb.*) | |
*(.scommon) | |
*(.dynbss) | |
*(.bss .bss.* .gnu.linkonce.b.*) | |
*(COMMON) | |
. = ALIGN(8); | |
_ebss = .; | |
_end = .; | |
} > main_ram | |
} | |
PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# remainder of parts are copied from LiteX demo directory | |
# gist filenames cannot have / in them, but this is fw/Makefile | |
include ../include/generated/variables.mak | |
include $(SOC_DIRECTORY)/software/common.mak | |
OBJECTS = donut.o helloc.o crt0.o main.o | |
all: fw.bin | |
%.bin: %.elf | |
$(OBJCOPY) -O binary $< $@ | |
ifneq ($(OS),Windows_NT) | |
chmod -x $@ | |
endif | |
vpath %.a $(PACKAGES:%=../%) | |
fw.elf: $(OBJECTS) | |
$(CC) $(LDFLAGS) -T $(FW_DIRECTORY)/linker.ld -N -o $@ \ | |
$(OBJECTS) \ | |
$(PACKAGES:%=-L../%) \ | |
-Wl,--whole-archive \ | |
-Wl,--gc-sections \ | |
-Wl,-Map,$@.map \ | |
$(LIBS:lib%=-l%) | |
ifneq ($(OS),Windows_NT) | |
chmod -x $@ | |
endif | |
# pull in dependency info for *existing* .o files | |
-include $(OBJECTS:.o=.d) | |
donut.o: CFLAGS += -w | |
VPATH = $(FW_DIRECTORY):$(FW_DIRECTORY)/cmds:$(CPU_DIRECTORY) | |
%.o: %.c | |
$(compile) | |
%.o: %.S | |
$(assemble) | |
clean: | |
$(RM) $(OBJECTS) fw.elf fw.bin .*~ *~ | |
.PHONY: all clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BaseSoC(SoCCore): | |
def __init__(self, sys_clk_freq=75e6, with_led_chaser=True, **kwargs): | |
platform = platform_whatever.Platform() | |
# ... | |
SoCCore.__init__(self, platform, sys_clk_freq, ident="whatever...", | |
integrated_rom_size = 0x0, | |
integrated_sram_size = 0, | |
integrated_main_ram_size = 0x8000, | |
cpu_reset_address = self.mem_map.get("main_ram"), | |
ident_version = True) | |
# build firmware, but not a BIOS | |
self.cpu.use_rom = True | |
self.integrated_rom_initialized = True | |
# ... | |
def init_mems(self, **kwargs): | |
self.init_rom('main_ram', get_mem_data(os.path.join(self.builder.software_dir, "fw", "fw.bin"), endianness = 'little', data_width = 32)) | |
def main(): | |
# ... | |
builder = Builder(soc, **parser.builder_argdict) | |
if args.build: | |
for package in builder.software_packages: | |
if package[0] == "bios": | |
builder.software_packages.remove(package) | |
break | |
builder.add_software_package('fw', src_dir = '../../../../fw') | |
print(builder.software_packages) | |
builder.build(**parser.toolchain_argdict) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment