OS in D language
Re: OS in D language
I looked into it, and found that "gcc-gdc" is just an old gcc built with an old gdc and distributed as binaries. It's still not officially supported by GCC, and the version available from cygwin is one from 2004... [Linky]
"Sufficiently advanced stupidity is indistinguishable from malice."
Re: OS in D language
Oh, that's bad !Zenith wrote:I looked into it, and found that "gcc-gdc" is just an old gcc built with an old gdc and distributed as binaries. It's still not officially supported by GCC, and the version available from cygwin is one from 2004... [Linky]
"Programmers are tools for converting caffeine into code."
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
The latest version of GCC that GDC supports is 4.1.x so I've downloaded the latest source, now I'm building my own cross compiler from the sources of binutils, GCC, and GDC under Cygwin.
EDIT:
I'm compiling a GCC cross compiler (targeting i586-elf) with GDC patched in.
It's crashing on gcc/d/d-lang.cc saying D_OS_VERSYM is unidentified. I trace it down, and I see that D_OS_VERSYM is being declared in:
gcc/d/target-ver-syms.h:
Ummm.. "elf*) ;;" ? Setting this string to NULL causes compile errors ([url="http://forums.pittgeeks.org/viewtopic.php?f=38&t=702&p=4534"]ref[/url]). Though it says target, I'll using values like Win32, Cygwin, etc and see what works.
EDIT 2: Now I'm getting "kernel.kmain.d:0: error: code model 'kernel' not supported in the 32 bit mode"
EDIT:
I'm compiling a GCC cross compiler (targeting i586-elf) with GDC patched in.
It's crashing on gcc/d/d-lang.cc saying D_OS_VERSYM is unidentified. I trace it down, and I see that D_OS_VERSYM is being declared in:
gcc/d/target-ver-syms.h:
Code: Select all
target=$1
target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
d_target_os=`echo $target_os | sed 's/^\([A-Za-z_]+\)/\1/'`
case "$d_target_os" in
aix*) d_os_versym=aix ; d_unix=1 ;;
coff*) ;;
cygwin*) d_os_versym=cygwin ; d_unix=1 ;;
darwin*) d_os_versym=darwin ; d_unix=1 ;;
elf*) ;;
freebsd*) d_os_versym=freebsd ; d_unix=1 ;;
linux*) d_os_versym=linux ; d_unix=1 ;;
mingw32*) d_os_versym=Win32; d_windows=1 ;;
pe*) case "$target" in
*-skyos*-*) d_os_versym=skyos ; d_unix=1 ;;
esac
;;
skyos*) d_os_versym=skyos ; d_unix=1 ;; # Doesn't actually work because SkyOS uses i386-skyos-pe
solaris*) d_os_versym=solaris; d_unix=1 ;;
sysv3*) d_os_versym=sysv3; d_unix=1 ;;
sysv4*) d_os_versym=sysv4; d_unix=1 ;;
*bsd*) d_os_versym=bsd ; d_unix=1 ;;
*) d_os_versym="$d_target_os"
esac
case "$target_cpu" in
alpha*) d_cpu_versym=Alpha ; d_cpu_versym64=Alpha64 ;;
arm*) d_cpu_versym=ARM ;;
i*86) d_cpu_versym=X86 ; d_cpu_versym64=X86_64 ;;
mips*) d_cpu_versym=MIPS ; d_cpu_versym64=MIPS64 ;;
*ppc*) d_cpu_versym=PPC ; d_cpu_versym64=PPC64 ;;
powerpc*)d_cpu_versym=PPC ; d_cpu_versym64=PPC64 ;;
sparc*) d_cpu_versym=SPARC ; d_cpu_versym64=SPARC64 ;;
x86_64) d_cpu_versym=X86 ; d_cpu_versym64=X86_64 ;;
esac
if test -n "$d_cpu_versym"; then
echo "#define D_CPU_VERSYM \"$d_cpu_versym\""
fi
if test -n "$d_cpu_versym64"; then
echo "#define D_CPU_VERSYM64 \"$d_cpu_versym64\""
fi
if test -n "$d_os_versym"; then
echo "#define D_OS_VERSYM \"$d_os_versym\""
fi
EDIT 2: Now I'm getting "kernel.kmain.d:0: error: code model 'kernel' not supported in the 32 bit mode"
My OS is Perception.
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
I finally have the compiler set up and working. I'm trying to write a barebones D kernel.
Everything is linking correctly, however I'm doing this as follows:
I wrote an assembly stub that defined the multiboot header and jumped into _main then hangs.
Here is my kernel.main.d:
and here is my linker script:
It links fine, but the kernel then triple faults. Apparently it might be a linker issue since a lot of this thread warns that linker issues are the biggest barrier to using D?
I also suspect it may be a runtime issue because of
"byte *videoram = cast(byte *)0xb8000;"
The D programming specification states that "cast" is the equivalent of a dynamic_cast in C++, so then how do I do a static typecast?
I would really appreciate some help on exactly the runtime environment that is needed from others who have used D.
Everything is linking correctly, however I'm doing this as follows:
I wrote an assembly stub that defined the multiboot header and jumped into _main then hangs.
Here is my kernel.main.d:
Code: Select all
module kernel.main;
extern(C) void main(uint magic, uint addr)
{
byte *videoram = cast(byte *)0xb8000;
videoram[0] = 65;
videoram[1] = 0x07;
}
Code: Select all
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
/* 3GB+1MB virtual / 1MB physical */
. = 0xC0100000;
.text : AT(ADDR(.text) - 0xC0000000)
{
code = .; _code = .; __code = .;
*(.text)
*(.rodata*)
/*. = ALIGN(4096);*/
}
.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
{
data = .; _data = .; __data = .;
*(.data)
/*. = ALIGN(4096);*/
__CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) *(.ctors) LONG(0) __CTOR_END__ = .;
__DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) *(.dtors) LONG(0) __DTOR_END__ = .;
}
.bss : AT(ADDR(.bss) - 0xC0000000)
{
_sbss = .;
bss = .; _bss = .; __bss = .;
*(COMMON)
*(.bss)
_ebss = .;
/*. = ALIGN(4096);*/
}
end = .; _end = .; __end = .;
}
I also suspect it may be a runtime issue because of
"byte *videoram = cast(byte *)0xb8000;"
The D programming specification states that "cast" is the equivalent of a dynamic_cast in C++, so then how do I do a static typecast?
I would really appreciate some help on exactly the runtime environment that is needed from others who have used D.
My OS is Perception.
Re: OS in D language
Well, you need cross compilation to support compiling without default binutils, etc.quanganht wrote:Testing now. I guess gdc will be include in gcc source code soon ~> cross-compiler no longer be the problem !
Hey! That was us. You can set it to anything you like. It is "XOmB" or "PGOS" or something for us.MessiahAndrw wrote:Setting this string to NULL causes compile errors (ref)
That should work fine. What is it doing when it returns from main? Because, well, that is always fun. I assume that the video memory is mapped correctly in your assembly.MessiahAndrw wrote:I also suspect it may be a runtime issue because of
"byte *videoram = cast(byte *)0xb8000;"
Maybe I will extract a barebones from our code base. It will be 64-bit though.
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
That is a brilliant idea!Wilkie wrote:Maybe I will extract a barebones from our code base. It will be 64-bit though.
When it returns from main my assembler stub calls hlt. No interrupts are enabled,
Now GDC is complaining it needs object.d ?!
It would be good if you could explain exactly what sort of runtime is required and for what.
Thanks!
My OS is Perception.
Re: OS in D language
MessiahAndrw and any others:
First:
You will need a gdc built against nothing that targets your architecture (build a cross compiler). You will need gcc 4.1.2 and gdc 0.24 for it to work without hassle. It will complain about D_OS_VERSYM, which you should define as any arbitrary string. Like this:
MessiahAndrw, you have already accomplished this.
Second:
Then have no standard library when building your actual kernel. That is, build with these flags to gdc: (written as it would be in a makefile)
Third:
The thing about gdc...it expects the runtime calls to be there and all 'magic' to be accounted for. You will need:
In XOmB's code:
Eventually, in userland, you may need va_args as part of your user runtime (or your kernel, to each their own), which is COMPLETE magic in gdc as well. You will need to have std/stdarg.d, you can use the one from XOmB. The file, as you can see, has an empty implementation, yet, the compiler knows how to handle it automagically.
So... here is what you can do. Create a directory for your kernel runtime environment, add it to the include path (with the -I flag). Place all of the above in this directory and link all of them to your kernel's executable. You will have:
klibd
--object.d
--dstubs.d
--invariant.d
--gcc
----builtins.d
--std
----intrinsic.d
----stdarg.d
----c
------stdarg.d
----typeinfo
------ti_* (just steal from us!)
Will you be my guinea pig?
When and if you confirm this to be workable, we can produce a D bare bones to release to the public domain.
First:
You will need a gdc built against nothing that targets your architecture (build a cross compiler). You will need gcc 4.1.2 and gdc 0.24 for it to work without hassle. It will complain about D_OS_VERSYM, which you should define as any arbitrary string. Like this:
Code: Select all
const char* cygwin_d_os_versym = "MyOS";
Second:
Then have no standard library when building your actual kernel. That is, build with these flags to gdc: (written as it would be in a makefile)
Code: Select all
DFLAGS = -nostdlib -nodefaultlibs -g -mcmodel=kernel
The thing about gdc...it expects the runtime calls to be there and all 'magic' to be accounted for. You will need:
- all of the typeinfo-ish stuff
- the runtime stubs and
- object.d (which is complete magic)
In XOmB's code:
- object.d - place at root of include path
- builtins.d - you will need this, it allows gcc 'magic' for va_args. We don't use variadics in the kernel. Note: it looks for gcc/builtins.d in the include path.
- std - some of the internals of the runtime. Should also be rooted in the include path.
- runtime stubs - You know what... just use ours. BSD'd for your freedom. It can be anywhere, just has to be linked.
- invariant.d - just more D runtime bull, copy from us. Can be anywhere, simply needs linked.
Eventually, in userland, you may need va_args as part of your user runtime (or your kernel, to each their own), which is COMPLETE magic in gdc as well. You will need to have std/stdarg.d, you can use the one from XOmB. The file, as you can see, has an empty implementation, yet, the compiler knows how to handle it automagically.
So... here is what you can do. Create a directory for your kernel runtime environment, add it to the include path (with the -I flag). Place all of the above in this directory and link all of them to your kernel's executable. You will have:
klibd
--object.d
--dstubs.d
--invariant.d
--gcc
----builtins.d
--std
----intrinsic.d
----stdarg.d
----c
------stdarg.d
----typeinfo
------ti_* (just steal from us!)
Will you be my guinea pig?
When and if you confirm this to be workable, we can produce a D bare bones to release to the public domain.
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
Wouldn't this be much easier to do using mixins since I see a lot of redundant code?Wilkie wrote: ----typeinfo
------ti_* (just steal from us!)
EDIT:
Okay, I had to add a few extra files (kernel/core/system.d and kernel/core/util.d).
It compiles without error, but when linking I get this:
Code: Select all
util.o: In function `_D4kernel4core4util4itoaFAaalZAa':
./source/kernel/core/util.d:374: undefined reference to `__umoddi3'
./source/kernel/core/util.d:375: undefined reference to `__udivdi3'
My OS is Perception.
Re: OS in D language
You guy are so fast! So, gdc huh ? I've been trying so hard with ldc ( and got nothing ). Well, it's good. Go for gdc now.
"Programmers are tools for converting caffeine into code."
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
Finally!
I have it!
Here is my file layout:
I've built my first D kernel targeting elf-i586. GRUB loads the kernel at 1MB, then in my assembly stub I map the 4MB page starting at 3GB to point to 0, push the multiboot header info on to the stack, then call main.
Now my simple higher-half D kernel:
prints a nice A in the top left of my screen Go D!
EDIT: And about those other errors, I had to link with libgcc.a. It's OS independent code that has a bunch of intrinsic arithmetic functions.
I'm going to edit my directory structure to separate the runtime from my kernel, and switch over to a makefile.
Can you tell me what features of the D language are not supported, and also what do I do about new/delete (where do I connect my allocator and such?)
Now to rewrite my kernel in D (It's probably a good thing doing a full rewrite once in a while to minimize bloat).
I have it!
Here is my file layout:
Code: Select all
build.bat -- calls Cygwin's bash and executes the shell script
build.sh -- my shell script that does the compiling and linking
loader.asm -- my assembly stub
main.d
object.d
link.ld -- linker script
build/ -- where my object files go
core/dstubs.d ------- from here on down it's all runtime stuff
core/invariant.d
core/system.d
core/util.d
std/intrinsic.d
std/stdarg.d
std/c/stdarg.d
std/typeinfo/ti_*.d -- 35 files
gcc/builtins.d
Now my simple higher-half D kernel:
Code: Select all
extern(C) void main(uint magic, void *phymbinfo)
{
ubyte *videoram = cast(ubyte *)0xb8000 + 0xC0000000;
videoram[0] = 65;
videoram[1] = 0x07;
}
EDIT: And about those other errors, I had to link with libgcc.a. It's OS independent code that has a bunch of intrinsic arithmetic functions.
I'm going to edit my directory structure to separate the runtime from my kernel, and switch over to a makefile.
Can you tell me what features of the D language are not supported, and also what do I do about new/delete (where do I connect my allocator and such?)
Now to rewrite my kernel in D (It's probably a good thing doing a full rewrite once in a while to minimize bloat).
My OS is Perception.
Re: OS in D language
Is it really necessary to get GCC 4.1.2 ? (because i'm using 4.3.2 )
"Programmers are tools for converting caffeine into code."
- AndrewAPrice
- Member
- Posts: 2299
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: OS in D language
Well, yes and no.quanganht wrote:Is it really necessary to get GCC 4.1.2 ? (because i'm using 4.3.2 )
The patch that comes with GDC can only be applied to certain versions of GCC, the latest being 4.1.x. If you really wanted to you could patch it yourself you could, on the first attempt I did try patching 4.3.2 and but it failed and I didn't want to hunt through the source manually so I just downloaded 4.1.2 and it worked without a flaw.
My OS is Perception.
Re: OS in D language
So can you make an detailed Wiki page?MessiahAndrw wrote: I just downloaded 4.1.2 and it worked without a flaw.
i'm stucking with expression.dmd.o: it says there is no complex.h
Edit: Killed it, but stuck at another point: iosfwd,cstdio... is missing.
EDIT 2: Oh silly me! I totally forgot to patch the top level src. That's why I keep stucking Trying agian !
Err. ld tells: can't find -lstdc++ ???
"Programmers are tools for converting caffeine into code."
Re: OS in D language
Not completely necessary. The wiki already contains the information to build a gcc cross-compiler here. A link off of that page gives info about the 64-bit variant.quanganht wrote:So can you make an detailed Wiki page?
The INSTALL documentation given with gdc gives information about patching gcc.
Therefore, all relevant information is available, with the exception of the step I outlined in my previous post about editing (after configuration) one line to allow it to compile.
Re: OS in D language
That is great news! Congrats on your achievement thus far. D is garbage collected, but the stubs have this capability disabled, so you'd probably just want to write the stubs for gc.malloc and gc.free (I believe) and then call them. A peek at a runtime implementation might help. Of course, you are edging a great debate to kernel heap allocations. My advice is to try and avoid them in your rewrite and just use directly a physical memory manager \ page allocator of your own design. This keeps you from doing "stupid things."MessiahAndrw wrote:Can you tell me what features of the D language are not supported, and also what do I do about new/delete (where do I connect my allocator and such?)
Doing this, you limit yourself, language-wise, to the static-subset of D. Anything that uses the D runtime stubs to allocate memory on your behalf cannot be used. You can do array slicing and casting pointers to arrays and the like, but you cannot create dynamic arrays or use dynamic array operations (that is, append). You cannot use classes and will probably prefer to use structs. You can, of course, use the entirety of the compile-time facilities (mixins, templates, and static conditionals), which is really where the power will come. You can use inline assembly. This includes the 'naked' directive (except in ldc currently, which is a huge drawback to porting our code).
You may prove me wrong.
For userland, you will have to port a C runtime (newlib) and\or a D runtime (phobos, tango). Look at reference implementations, much of which you can copy verbatim. They make calls to a malloc and are easily understood. From there, you can interface with your page allocator.
Also, you had to link to libgcc.a? That seems like a considerable trap. I wonder why you had to do this.