Discussion:
Need help making minimal bare metal ARM Cortex-M D program
Mike
2013-11-24 12:42:59 UTC
Permalink
I am very new to D, but I finally got my toolchain compiled and
working. I'm using LDC. I failed with GDC and eventually gave
up.

I am trying to get an _extremely_ minimal bare metal ARM Cortex-M
HelloWorld-type program compiled and executed on my STM32F4-based
hardware. I know the toochain is buggy for arm right now, but
I'm hoping I can do something about that if I can just get
started.

Here's the basic C code and linker script for my hardware. It
doesn't actually print "hello world". I intend to add that after
I get the following basic code compiled and downloaded to my
hardware.

/***************************
* start.c
****************************/
// defined in linker script
extern unsigned long _stack_end;

void handler_reset(void)
{
//Print hello world using SWI
}

__attribute__ ((section(".interrupt_vector")))
void (* const table_interrupt_vector[])(void) =
{
(void *) &_stack_end,
handler_reset
};

/***************************
* linkerscript.ld
****************************/
MEMORY
{
CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k
SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k
}

SECTIONS
{
.ccm (NOLOAD) :
{
. = ALIGN(4);
*(.ccm)
. = ALIGN(4);
} >CCRAM

stackTop = ORIGIN(CCRAM) + LENGTH(CCRAM);
Mike
2013-11-24 12:45:17 UTC
Permalink
Please delete this thread. I hit a tab and a space while typing
my code, resulting in a premature submit. I will make a separate
complete post.

Sorry,
Mike
Iain Buclaw
2013-11-24 12:50:32 UTC
Permalink
Post by Mike
Please delete this thread. I hit a tab and a space while
typing my code, resulting in a premature submit. I will make a
separate complete post.
Sorry,
Mike
This is a mailing list, not a forum. We can't delete things here.
:o)
Iain Buclaw
2013-11-24 12:53:41 UTC
Permalink
Post by Mike
I am very new to D, but I finally got my toolchain compiled and
working. I'm using LDC. I failed with GDC and eventually gave
up.
I know Johannes has some patches yet to trickle down into gdc.
And druntime is does not support ARM fully in 2.063, but it would
be helpful if you could take some time to let people know what
went wrong when you tried things, rather than just giving up.
Otherwise, nothing will get fixed.
Mike
2013-11-24 13:19:43 UTC
Permalink
Post by Iain Buclaw
Post by Mike
I am very new to D, but I finally got my toolchain compiled
and working. I'm using LDC. I failed with GDC and eventually
gave up.
I know Johannes has some patches yet to trickle down into gdc.
And druntime is does not support ARM fully in 2.063, but it
would be helpful if you could take some time to let people know
what went wrong when you tried things, rather than just giving
up. Otherwise, nothing will get fixed.
I don't think the problems I encountered with GDC were the fault
of GDC. They were my fault. I have more to learn about the
Linux platform. It seems the GCC toolchain is highly dependent
on the host platform and if things aren't set up just right, you
get errors that have nothing to do with the actual problem.

Also, when I tried to follow the crosstools instructions here
(http://wiki.dlang.org/GDC/Cross_Compiler) I found that the
latest crosstools was missing some of the options that are needed.

I have been quite successful using the GNU Tools for ARM Embedded
Processors here (https://launchpad.net/gcc-arm-embedded), and I
hope to merge this with the GDC code and give it another try. I
tried it this weekend, but I wasn't even able to get the shell
scripts to run without errors.

And, I didn't JUST give up. I worked on it all weekend, every
weekend, for the past 3 weeks. I'm tired of the platform
dependencies, and I'm anxious to just get started. Once I get
more familiar with D and have some working code, I'll give GDC
another try.
Johannes Pfau
2013-11-24 14:21:42 UTC
Permalink
Am Sun, 24 Nov 2013 14:19:43 +0100
Post by Mike
Post by Iain Buclaw
Post by Mike
I am very new to D, but I finally got my toolchain compiled
and working. I'm using LDC. I failed with GDC and eventually
gave up.
I know Johannes has some patches yet to trickle down into gdc.
And druntime is does not support ARM fully in 2.063, but it
would be helpful if you could take some time to let people know
what went wrong when you tried things, rather than just giving
up. Otherwise, nothing will get fixed.
Cortex-M is the 'bare metal' branch of ARM where you usually don't run
linux so druntime won't work anyway. There are some compiler fixes in
my branch that could be interesting though:
https://github.com/jpf91/GDC/commits/arm

BTW: I'll start merging back the fixes to gdc master this week. Some
fixes have to be merged into phobos upstream though so it might take
some time.
Post by Mike
I don't think the problems I encountered with GDC were the fault
of GDC. They were my fault. I have more to learn about the
Linux platform. It seems the GCC toolchain is highly dependent
on the host platform and if things aren't set up just right, you
get errors that have nothing to do with the actual problem.
Also, when I tried to follow the crosstools instructions here
(http://wiki.dlang.org/GDC/Cross_Compiler) I found that the
latest crosstools was missing some of the options that are needed.
You mean options for bare metal builds or options described in the
wiki? I'm not sure if crosstool-NG works well with bare metal builds.
Post by Mike
I have been quite successful using the GNU Tools for ARM Embedded
Processors here (https://launchpad.net/gcc-arm-embedded), and I
hope to merge this with the GDC code and give it another try. I
tried it this weekend, but I wasn't even able to get the shell
scripts to run without errors.
And, I didn't JUST give up. I worked on it all weekend, every
weekend, for the past 3 weeks. I'm tired of the platform
dependencies, and I'm anxious to just get started. Once I get
more familiar with D and have some working code, I'll give GDC
another try.
GCC build scripts can be annoying, especially when cross-compiling.
Your best bet is still crosstool-NG though, what exactly are the
missing options?
Mike
2013-11-24 14:44:12 UTC
Permalink
Post by Johannes Pfau
Cortex-M is the 'bare metal' branch of ARM where you usually
don't run
linux so druntime won't work anyway. There are some compiler
fixes in
https://github.com/jpf91/GDC/commits/arm
I'm aware of the druntime will not work, which is why I'm trying
to find a way to write and compile code _without_ the druntime or
phobos. See my re-post.
Post by Johannes Pfau
Post by Mike
Also, when I tried to follow the crosstools instructions here
(http://wiki.dlang.org/GDC/Cross_Compiler) I found that the
latest crosstools was missing some of the options that are
needed.
You mean options for bare metal builds or options described in
the
wiki? I'm not sure if crosstool-NG works well with bare metal
builds.
GCC build scripts can be annoying, especially when
cross-compiling.
Your best bet is still crosstool-NG though, what exactly are the
missing options?
A couple of the options don't seem to exist in crosstools.
Specifically "Go to C compiler, select Other languages and enter
d". Pretty hard to tell the compiler to support D without this
option.

The GNU Tools for ARM scripts are specifically written for
cross-compiling, and even Canadian cross compiling. When I run
the build scripts, I get:

cat ~/mylongdir/src/gcc/gcc/BASE-VER: No such file or directory.

I looked through the shell script, but code like this

GCC_VER=`cat $SRCDIR/$GCC/gcc/BASE-VER`
GCC_VER_NAME=`echo $GCC_VER | cut -d'.' -f1,2 | sed -e 's/\./_/g'`

is a little hard for me to figure out.

Again, the problem here is not with GDC; it's that I don't know
enough about the Linux tools to know what its trying to do here
and what I can do about it.

LLVM, clang, and LDC built on the first try after 3 weekends
struggling with GCC.
jerro
2013-11-24 15:32:02 UTC
Permalink
Post by Mike
A couple of the options don't seem to exist in crosstools.
Specifically "Go to C compiler, select Other languages and
enter d". Pretty hard to tell the compiler to support D
without this option.
Have you set 'Try features marked as EXPERIMENTAL'?
Are you using a recent version of crosstool-NG? And in case
this isn't clear, there isn't a 'D' option to choose from,
you need to type 'D' into the field.
Mike
2013-11-24 15:42:06 UTC
Permalink
Post by jerro
Post by Mike
A couple of the options don't seem to exist in crosstools.
Specifically "Go to C compiler, select Other languages and
enter d". Pretty hard to tell the compiler to support D
without this option.
Have you set 'Try features marked as EXPERIMENTAL'?
Are you using a recent version of crosstool-NG? And in case
this isn't clear, there isn't a 'D' option to choose from,
you need to type 'D' into the field.
Yes, I tried experimental features, obsolete features, and number
of other things. I know there isn't a D option to check. I was
fully expecting a text field to type the letter 'D' into, but the
"Other languages" option does not exist. It appears to have been
replaced with a "C++" check option.

Give it a try yourself, and you'll see what I mean.
jerro
2013-11-24 17:18:22 UTC
Permalink
It seems languages other than C are disabled for bare metal
builds. You could try searching for cc.ini in your crosstool-ng
installation and commenting out the line

if ! BARE_METAL

and

endif # ! BARE_METAL
Johannes Pfau
2013-11-24 18:38:04 UTC
Permalink
Am Sun, 24 Nov 2013 18:18:22 +0100
Post by jerro
It seems languages other than C are disabled for bare metal
builds. You could try searching for cc.ini in your crosstool-ng
installation and commenting out the line
if ! BARE_METAL
and
endif # ! BARE_METAL
Good to know. I'll prepare a patch
( I'm currently implementing cross-native builds for crosstool-NG
anyway)
Mike
2013-12-01 05:23:13 UTC
Permalink
Post by Johannes Pfau
Am Sun, 24 Nov 2013 18:18:22 +0100
Post by jerro
It seems languages other than C are disabled for bare metal
builds. You could try searching for cc.ini in your
crosstool-ng installation and commenting out the line
if ! BARE_METAL
and
endif # ! BARE_METAL
Good to know. I'll prepare a patch
( I'm currently implementing cross-native builds for
crosstool-NG
anyway)
Just tried again with crosstools-ng 1.19.0. I commented out the
appropriate lines in my cc.ini file, but the build failed with...

" The following requested languages could not be built: d "

... in the build.log file.

Also, the instructions here
(http://gdcproject.org/wiki/Cross%20Compiler/crosstool-NG) say:

"If druntime & phobos do not yet compile for your target you can
disable them:

Start ct-ng menuconfig, go to "C compiler" and add
"--disable-libphobos" to "Core gcc extra config" and "gcc extra
config". "

While the "Core gcc extra config" option exists, "gcc extra
config" does not.

The quest continues...
Mike
2013-12-01 06:00:06 UTC
Permalink
On Sunday, 24 November 2013 at 18:38:19 UTC, Johannes Pfau
Post by Johannes Pfau
Am Sun, 24 Nov 2013 18:18:22 +0100
Post by jerro
It seems languages other than C are disabled for bare metal
builds. You could try searching for cc.ini in your
crosstool-ng installation and commenting out the line
if ! BARE_METAL
and
endif # ! BARE_METAL
Good to know. I'll prepare a patch
( I'm currently implementing cross-native builds for
crosstool-NG
anyway)
Just tried again with crosstools-ng 1.19.0. I commented out
the appropriate lines in my cc.ini file, but the build failed
with...
" The following requested languages could not be built: d "
... in the build.log file.
Also, the instructions here
"If druntime & phobos do not yet compile for your target you
Start ct-ng menuconfig, go to "C compiler" and add
"--disable-libphobos" to "Core gcc extra config" and "gcc extra
config". "
While the "Core gcc extra config" option exists, "gcc extra
config" does not.
The quest continues...
Thinking about this a little more, I figured the only way GCC
would not no about D is if the GCC sources were not patched...and
sure enough, I had crosstools pointing to the wrong folder. My
mistake.
Mike
2013-12-01 08:58:01 UTC
Permalink
Post by Mike
On Sunday, 24 November 2013 at 18:38:19 UTC, Johannes Pfau
Post by Johannes Pfau
Am Sun, 24 Nov 2013 18:18:22 +0100
Post by jerro
It seems languages other than C are disabled for bare metal
builds. You could try searching for cc.ini in your
crosstool-ng installation and commenting out the line
if ! BARE_METAL
and
endif # ! BARE_METAL
Good to know. I'll prepare a patch
( I'm currently implementing cross-native builds for
crosstool-NG
anyway)
Just tried again with crosstools-ng 1.19.0. I commented out
the appropriate lines in my cc.ini file, but the build failed
with...
" The following requested languages could not be built: d "
... in the build.log file.
Also, the instructions here
"If druntime & phobos do not yet compile for your target you
Start ct-ng menuconfig, go to "C compiler" and add
"--disable-libphobos" to "Core gcc extra config" and "gcc
extra config". "
While the "Core gcc extra config" option exists, "gcc extra
config" does not.
The quest continues...
Thinking about this a little more, I figured the only way GCC
would not no about D is if the GCC sources were not
patched...and sure enough, I had crosstools pointing to the
wrong folder. My mistake.
I was finally able to build a GDC cross compiler using GCC 4.8.2,
the GDC 4.8 branch, and crosstools-ng 1.19.0. However, I found
the following errors in the instructions located here
(http://gdcproject.org/wiki/Cross%20Compiler/crosstool-NG)

1. The "Other Languages" option does not appear for a bare metal
build. You must modify the cc.ini file to make it available per
jerro's insructions above. Thanks jerro
2. The "Core gcc extra config" option exists, but the "gcc extra
config" does not. It doesn't appear to be necessary, but I have
yet to test this toolchain.
3. The "Paths and misc options, Local tarballs directory" option
does not seem to be correct. For me, I had to go to "C Compiler"
-> "gcc version" and choose "Custom gcc" and point crosstools-ng
to the folder containing the merged GCC/GDC source code.

I hope this information is useful to someone.
Johannes Pfau
2013-12-01 11:17:12 UTC
Permalink
Am Sun, 01 Dec 2013 09:58:01 +0100
Post by Mike
I was finally able to build a GDC cross compiler using GCC 4.8.2,
the GDC 4.8 branch, and crosstools-ng 1.19.0. However, I found
the following errors in the instructions located here
(http://gdcproject.org/wiki/Cross%20Compiler/crosstool-NG)
BTW: The new location is
http://wiki.dlang.org/GDC/Cross_Compiler/crosstool-NG
Post by Mike
1. The "Other Languages" option does not appear for a bare metal
build. You must modify the cc.ini file to make it available per
jerro's insructions above. Thanks jerro
That's a bug in crosstool-NG, I'll try to get it fixed.
Post by Mike
2. The "Core gcc extra config" option exists, but the "gcc extra
config" does not. It doesn't appear to be necessary, but I have
yet to test this toolchain.
It's indeed not necessary for bare-metal builds. That's probably
because the instructions weren't tested on bare metal builds.
Post by Mike
3. The "Paths and misc options, Local tarballs directory" option
does not seem to be correct. For me, I had to go to "C Compiler"
-> "gcc version" and choose "Custom gcc" and point crosstools-ng
to the folder containing the merged GCC/GDC source code.
Back when I wrote those instructions the "Custom gcc" option didn't
exist. Custom gcc will work just fine, but there's a subtle difference:
crosstool-NG may automatically apply some patches for certain GCC
versions. It won't apply those patches when using the "Custom gcc"
option.

However, the method described in the wiki only works if the patched
sources are packaged into a new tarball with exactly the same name as
the original tarball (gcc-4.7.1.tar.bz2/gcc-4.8.2.tar.bz2/...). Then
crosstool-NG may have cached the extracted sources and those have to be
deleted. And nowadays crosstool-NG might actually prefer .tar.xz files,
so if you have an unpatched tar.xz file in the source directory it
file has to be deleted. I'll probably add some text about these issues
to the documentation.
Post by Mike
I hope this information is useful to someone.
It definitely is. Thanks for the feedback!
Ellery Newcomer
2013-11-24 17:35:57 UTC
Permalink
Post by Johannes Pfau
Am Sun, 24 Nov 2013 14:19:43 +0100
Post by Iain Buclaw
Post by Mike
I am very new to D, but I finally got my toolchain compiled
and working. I'm using LDC. I failed with GDC and eventually
gave up.
I know Johannes has some patches yet to trickle down into gdc.
And druntime is does not support ARM fully in 2.063, but it
would be helpful if you could take some time to let people know
what went wrong when you tried things, rather than just giving
up. Otherwise, nothing will get fixed.
Cortex-M is the 'bare metal' branch of ARM where you usually don't run
linux so druntime won't work anyway. There are some compiler fixes in
https://github.com/jpf91/GDC/commits/arm
BTW: I'll start merging back the fixes to gdc master this week. Some
fixes have to be merged into phobos upstream though so it might take
some time.
I actually tried to get a gdc build a week or two ago for a cortex-a8
using ng-crosstools-linaro. I managed to get up to compiling druntime,
which then was pointing to a commit prior to

https://github.com/D-Programming-Language/druntime/commit/541e7ba00d5e75426bb677d7f7548a47a904551f

so it failed. Then I figured I'd wait for your fixes.
Johannes Pfau
2013-12-01 13:35:57 UTC
Permalink
Am Sun, 24 Nov 2013 09:35:57 -0800
Post by Ellery Newcomer
Post by Johannes Pfau
Am Sun, 24 Nov 2013 14:19:43 +0100
Post by Iain Buclaw
Post by Mike
I am very new to D, but I finally got my toolchain compiled
and working. I'm using LDC. I failed with GDC and eventually
gave up.
I know Johannes has some patches yet to trickle down into gdc.
And druntime is does not support ARM fully in 2.063, but it
would be helpful if you could take some time to let people know
what went wrong when you tried things, rather than just giving
up. Otherwise, nothing will get fixed.
Cortex-M is the 'bare metal' branch of ARM where you usually don't
run linux so druntime won't work anyway. There are some compiler
https://github.com/jpf91/GDC/commits/arm
BTW: I'll start merging back the fixes to gdc master this week. Some
fixes have to be merged into phobos upstream though so it might take
some time.
I actually tried to get a gdc build a week or two ago for a cortex-a8
using ng-crosstools-linaro. I managed to get up to compiling
druntime, which then was pointing to a commit prior to
https://github.com/D-Programming-Language/druntime/commit/541e7ba00d5e75426bb677d7f7548a47a904551f
so it failed. Then I figured I'd wait for your fixes.
Hi,
as Iain started merging 2.064 the ARM branch merge will probably be
delayed until the 2.064 merge is complete. I updated my branch to
be on the last 2.063 revision which still compiles with gcc-4.8:
https://github.com/jpf91/GDC/commits/arm

It'd be awesome if you could help with some alpha-testing.
Unfortunately cross-compilers are completely untested and I'll first
have to make the test suite run for cross-compilers. But if you could
build a native compiler, run the test suite and unit tests and report
the results, that'd be awesome.

See http://wiki.dlang.org/GDC/Test_Suite
and http://wiki.dlang.org/GDC/Test_Suite#Running_unit_tests
for more information.
Mike
2013-11-24 13:00:37 UTC
Permalink
I am very new to D, but I finally got my toolchain compiled and
working. I'm using LDC. I failed with GDC and eventually gave
up.

I am trying to get an _extremely_ minimal bare metal ARM Cortex-M
HelloWorld-type program (no phobos, no runtime, nothing but what
I type myself) compiled and executed on my STM32F4-based
hardware. I know the toolchain is buggy for arm right now, but
I'm hoping I can do something about that if I can just get
started.

Here's the basic C code and linker script for my hardware. It
doesn't actually print "hello world". I intend to add that after
I get the following code compiled and downloaded to my hardware.

/***************************
* start.c
****************************/
// defined in linker script
extern unsigned long _stack_end;

void handler_reset(void)
{
//Print hello world using SWI
}

__attribute__ ((section(".interrupt_vector")))
void (* const table_interrupt_vector[])(void) =
{
(void *) &_stack_end,
handler_reset
};

/***************************
* linkerscript.ld
****************************/
MEMORY
{
CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k
SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k
}

_stack_end = ORIGIN(CCRAM) + LENGTH(CCRAM);

SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH

.text :
{
. = ALIGN(4);
KEEP(*(.interrupt_vector))
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
. = ALIGN(4);
} > flash
}

Can anyone out them tell me if/how this can be accomplished in D?

Is there some syntax equivalent to __attribute__
((section(".interrupt_vector")))?

Would the following give me a minimal reset_handler?

// compile with: ldc2 -c -nodefaultlib -noruntime
module reset_handler;

extern(C) __gshared void * _Dmodule_ref;
extern(C) void reset_handler()
{ }

I've seen some examples out on the web, but they all either use
C, or are written specifically for an x86/x86_64 platform. So
any help you could provide would be great to help me get started.