Hi there,
I’m slowly learning zig and embedded development on my spare time and my, long term, goal is to build a simple SDK for the Nintendo DS, based on libnds.
I already manage to get a very basic and hacky zig example (that you can found here) but it still use gcc arm and blocksds SDK (previously devkitpro) for linking.
My goal is to be able to run my code only with zig build system and package manager.
The first step is to be able to use zig for linking instead of gcc.
So I tried to tranform gcc args into zig cc ones, but not sure if I got it the right way.
Here is all the gcc args used for linking and the zig cc equivalent I used :
arm-none-eabi-gcc -mthumb=>zig cc -target thumb-freestanding-eabi. Isfreestandingthe equivalent ofnone?-mcpu=arm946e-s+nofp=>-mcpu=arm946e_s. I don’t know how to specifynofpoption, do you have any idea on how to do that ?-Wl,-Map,zig-nds-sample.map=>-fmodule-map-file=zig-nds-sample.map. Not sure about this one
.- There was also some
.specsfile which specify astartfilewhich is a.ofile that I added to the other.ofile to link. It’s my understanding of what is astartfilebut it may be something else, never worked with.specsfiles before. - There was also
linkinstruction in the spec files and I added them to the args, it was-Toptions pointing to.memfiles.
After a lot of try and error and reading, I still got an error which I don’t fully understand :
ld.lld: error: ./libnds/ds_arm9.ld:7: memory region not defined: ewram
>>> __ewram_end = ORIGIN(ewram) + LENGTH(ewram);
>>>
I never occurred such errors in C, I assumed the EWRAM nds memory region must be somehow initialized. Is this related to the .map file or the .mem files ?
Here is the ds_arm9.specs file :
%include <picolibc.specs>
%rename cc1plus blocksds_cc1plus
%rename cpp blocksds_cpp
%rename link blocksds_link
*cpp:
-D__NDS__ -D__BLOCKSDS__ -DARM9 %(blocksds_cpp)
*cc1_cpu:
-mcpu=arm946e-s+nofp
*cc1plus:
%(cpp) %(blocksds_cc1plus)
*link:
%(blocksds_link) -T %:getenv(BLOCKSDS /sys/crts/ds_arm9.mem) -T %:getenv(BLOCKSDS /sys/crts/ds_arm9.ld) --gc-sections --no-warn-rwx-segments --use-blx
*startfile:
%:getenv(BLOCKSDS /sys/crts/ds_arm9_crt0%O)
*lib:
%(libgcc)
And the picolibc.specs (BLOCKSDS used picolibc instead of newlibc :
%rename link picolibc_link
%rename cc1 picolibc_cc1
%rename cc1plus picolibc_cc1plus
*cc1:
%{!ftls-model:-ftls-model=local-exec} %(picolibc_cc1)
*cc1plus:
%{!ftls-model:-ftls-model=local-exec} %(picolibc_cc1plus)
*link:
%{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfprintf=__d_vfprintf} %{DPICOLIBC_DOUBLE_PRINTF_SCANF:--defsym=vfscanf=__d_vfscanf} %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfprintf=__f_vfprintf} %{DPICOLIBC_FLOAT_PRINTF_SCANF:--defsym=vfscanf=__f_vfscanf} %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfprintf=__l_vfprintf} %{DPICOLIBC_LONG_LONG_PRINTF_SCANF:--defsym=vfscanf=__l_vfscanf} %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfprintf=__i_vfprintf} %{DPICOLIBC_INTEGER_PRINTF_SCANF:--defsym=vfscanf=__i_vfscanf} %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfprintf=__m_vfprintf} %{DPICOLIBC_MINIMAL_PRINTF_SCANF:--defsym=vfscanf=__m_vfscanf} %(picolibc_link)
*lib:
--start-group %(libgcc) -lc --end-group
And the original command line from a blockds’s sample Makefile :
/opt/wonderful/toolchain/gcc-arm-none-eabi/bin/arm-none-eabi-gcc -o build/console_ansi.elf build/console_ansi/source/main.c.o -mthumb -mcpu=arm946e-s+nofp -L/opt/blocksds/core/libs/libnds/lib -Wl,-Map,build/console_ansi.map -Wl,--start-group -lnds9 -lc -Wl,--end-group -specs=/opt/blocksds/core/sys/crts/ds_arm9.specs
I know that I miss a lot of knowledge in embedded system to fully understand what I’m doing, but if someone can help me it would be awesome.
Thanks for reading me,
Andréas
P.S : Don’t be mad if I don’t answer, I’ll be on vacation in a couple of days.