OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 2:48 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 62 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Wed Dec 05, 2012 10:30 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
More changes needed.

libgcc/config.host:

Code:
*-*-rdos*)
  extra_parts="crtbegin.o crtend.o"
  ;;

...

i[34567]86-*-rdos*)
   tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
   ;;
x86_64-*-rdos*)
   tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
   ;;



The target specific file (under gcc/config/i386/rdos.h)

Code:

/* RDOS uses .exe suffix */
#undef TARGET_EXECUTABLE_SUFFIX
#define TARGET_EXECUTABLE_SUFFIX ".exe"

#define TARGET_OS_CPP_BUILTINS()                \
  do                                                                    \
    {                                                                   \
        builtin_define ("__RDOS__");            \
        builtin_assert ("system=rdos");         \
    }                                                                   \
  while (0)

/* RDOS headers are C++-aware (and often use C++).  */
#define NO_IMPLICIT_EXTERN_C



The RDOS thread-interface (probably under libgcc/config/gthr-rdos.h)

Code:

#ifndef GCC_GTHR_RDOS_H
#define GCC_GTHR_RDOS_H

/* RDOS threads specific definitions.
   calls functions in rdos.s module  */

#define __GTHREADS 1

#ifdef __cplusplus
extern "C" {
#endif

extern int __rdos_thread_once_init (void);
extern int __rdos_thread_once (int handle, void (*func) (void));

extern int __rdos_thread_key_create (int handle, void (*dtor) (void *));
extern int __rdos_thread_key_delete (int handle);
extern void * __rdos_thread_getspecific (int handle);
extern int __rdos_thread_setspecific (int handle, const void *ptr);

extern int __rdos_thread_mutex_init (void);
extern int __rdos_thread_mutex_lock (int handle);
extern int __rdos_thread_mutex_trylock (int handle);
extern int __rdos_thread_mutex_unlock (int handle);

#define __gthread_key_t int
#define __gthread_once_t int
#define __gthread_mutex_t int
#define __gthread_recursive_mutex_t int

#define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_mutex_init_function

static inline int
__gthread_active_p (void)
{
  return 1;
}

static inline int
__gthread_once (__gthread_once_t *once, void (*func) (void))
{
  return __rdos_thread_once (*(int *)once, func);
}

static inline int
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
{
  return __rdos_thread_key_create (*(int *)key, dtor);
}

static inline int
__gthread_key_delete (__gthread_key_t key)
{
  return __rdos_thread_key_delete ((int)key);
}

static inline void *
__gthread_getspecific (__gthread_key_t key)
{
  return __rdos_thread_getspecific ((int)key);
}

static inline int
__gthread_setspecific (__gthread_key_t key, const void *ptr)
{
  return __rdos_thread_setspecific ((int)key, ptr);
}

static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
  return __rdos_thread_mutex_lock (*(int *)mutex);
}

static inline int
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
{
  return __rdos_thread_mutex_trylock (*(int *)mutex);
}

static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
  return __rdos_thread_mutex_unlock (*(int *)mutex);
}

static inline void
__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
  *mutex = __rdos_thread_mutex_init ();
}

static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
{
  return __rdos_thread_mutex_lock (*(int *)mutex);
}

static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
{
  return __rdos_thread_mutex_trylock (*(int *)mutex);
}

static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
{
  return __rdos_thread_mutex_unlock (*(int *)mutex);
}

#ifdef __cplusplus
}
#endif

#endif /* ! GCC_GTHR_RDOS_H */



Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Wed Dec 05, 2012 2:17 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
I just managed to build my first 64-bit application for RDOS. It is 33k large, and it has the elf-64 format. :D

I've not yet managed to build the thread-interface for libgcc, but that might be secondary. The virtual address of the executable (0x400000) also seems less than optimal, but OTOH, it seems like the file has no relocations, so maybe it can be loaded anywhere?

Edit: There seems to be a bug in 4.7.2 related to libgcc gthr-bootstrap, so I will download a snapshot instead and provide the patch which defines the position of the thread include file.


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 3:43 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
rdos wrote:
The virtual address of the executable (0x400000) also seems less than optimal, but OTOH, it seems like the file has no relocations, so maybe it can be loaded anywhere?
Lack of relocations does not imply the executable is position-independent. The linker may well have hard coded some addresses at the static link phase. If you wish to change the load address either supply a linker script for your users or create a new script in the emulparams subdirectory of the ld source where you can set the default load address of the text segment.

rdos wrote:
It is 33k large
Did you expect it to be this big? If its just a simple 'Hello World' with a small footprint C library then you may want to try the "-z max-page-size=0x1000" linker option to see if it becomes smaller.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 4:29 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
jnc100 wrote:
rdos wrote:
The virtual address of the executable (0x400000) also seems less than optimal, but OTOH, it seems like the file has no relocations, so maybe it can be loaded anywhere?
Lack of relocations does not imply the executable is position-independent. The linker may well have hard coded some addresses at the static link phase. If you wish to change the load address either supply a linker script for your users or create a new script in the emulparams subdirectory of the ld source where you can set the default load address of the text segment.


OK. I'll look into that.

jnc100 wrote:
rdos wrote:
It is 33k large
Did you expect it to be this big? If its just a simple 'Hello World' with a small footprint C library then you may want to try the "-z max-page-size=0x1000" linker option to see if it becomes smaller.


It is not even a "Hello world" app, rather main doesn't do anything. OTOH, most of the space is used for symbols. The code itself is less than 1k.

BTW, does GCC (and GDB) support placing symbols in a separate file instead? I always use this option with OpenWatcom, as the symbol file is usually 10 times larger than the code.


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 4:54 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
rdos wrote:
OK. I'll look into that.
For more information see the OS Specific Toolchain wiki article about this. edit: I suggest you adapt the elf_x86_64.sh script to your needs.
rdos wrote:
BTW, does GCC (and GDB) support placing symbols in a separate file instead? I always use this option with OpenWatcom, as the symbol file is usually 10 times larger than the code.
Code:
gcc -g -o test.exe file1.c file2.c
objcopy --only-keep-debug test.exe test.debug
strip -g test.exe
gdb test.exe
(gdb) sy test.debug

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 6:29 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
jnc100 wrote:
rdos wrote:
OK. I'll look into that.
For more information see the OS Specific Toolchain wiki article about this. edit: I suggest you adapt the elf_x86_64.sh script to your needs.


I just looked into it, and it seems to be the right place. There are already some conditionals at the end which I could extend.

Since I want all 64-bit applications to be loaded at the start of the second PML4 entry + some offset for OS-specific stuff, the entry-point could be
0x0000008000100000.


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 7:25 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
There obviously is a bug in the base-address code, because GCC bootstrap fails if you setup TEXT_START_ADDRESS above 4G. :evil:

For the moment I'll have to depend on relocation not being necessary. I would notice pretty quick if the 64-bit application tries to access something below 4G since the whole first PML4 entry would be marked as kernel-only.

Correction: The problem seems to be something else, as a new build without changing TEXT_START_ADDRESS doesn't work either. Seems like there is some problem in the snapshot of GCC that I'm using.

Edit: It was my fault. :oops:


Last edited by rdos on Thu Dec 06, 2012 10:53 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 10:53 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
Building the whole tool set seems quite complicated, especially with custom thread support.

Therefore, here is the documentation of how to build the RDOS environment, which might be relevant for others. Psart of this should probably be added to the Wiki article:

Code:
export TARGET=rdos
export PREFIX=/usr/local/rdos

mkdir build-binutils
cd build-binutils
../binutils-2.23.1/configure --target=$TARGET --prefix=$PREFIX --disable-nls
make all
make install

export PATH=$PATH:$PREFIX/bin
mkdir build-gcc-noheader
cd build-gcc-noheader
../gcc-4.8-20121202/configure --target=$TARGET --prefix=$PREFIX  --disable-nls --enable-languages=c,c++ --without-headers --disable-threads
make all-gcc
make install-gcc
make all-target-libgcc
make install-target-libgcc

mkdir build-newlib
cd build-newlib
../newlib-1.20.0/configure --target=$TARGET --prefix=$PREFIX --disable-nls
make all
make install

mkdir build-gcc
cd build-gcc
../gcc-4.8-20121202/configure --target=$TARGET --prefix=$PREFIX  --disable-nls --enable-languages=c,c++ --enable-threads
make all-gcc
make install-gcc
make all-target-libgcc
make install-target-libgcc



Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 2:08 pm 
Offline
Member
Member

Joined: Thu Mar 25, 2010 11:26 pm
Posts: 1801
Location: Melbourne, Australia
Quote:
There obviously is a bug in the base-address code, because GCC bootstrap fails if you setup TEXT_START_ADDRESS above 4G
It might depend on which memory model you use. Perhaps 'small' is the default for gcc.

_________________
If a trainstation is where trains stop, what is a workstation ?


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Thu Dec 06, 2012 4:35 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
gerryg400 wrote:
Quote:
There obviously is a bug in the base-address code, because GCC bootstrap fails if you setup TEXT_START_ADDRESS above 4G
It might depend on which memory model you use. Perhaps 'small' is the default for gcc.


No, it was my fault. I did two things at once (because it takes half-an-hour to build binutils + GCC), so I forgot an "esac" in the script which produced the error.


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Fri Dec 07, 2012 4:43 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
I got the thread code in libgcc to compile, but the -mcmodel flag for GCC is probably set incorrectly since the linker complains about overflows. I've determined that the best cmodel should be CM_MEDIUM_PIC, but I've not figured out how to make that the default when building GCC. If somebody know, or know how to build newlib with that option, I'd appreciate some pointers.


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Fri Dec 07, 2012 8:37 am 
Offline
Member
Member

Joined: Mon Apr 09, 2007 12:10 pm
Posts: 775
Location: London, UK
Does 'CFLAGS=-mcmodel=medium -fpic ./configure; CFLAGS=-mcmodel=medium -fpic make' work when building newlib? Otherwise I guess you could play with redefining CC1_SPEC (link) in i386/rdos.h to include some defaults, although I'm not sure of the exact phrasing and whether or not this would allow the new default model to be overrode on the command line.

Regards,
John.

_________________
Tysos | rpi-boot


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Fri Dec 07, 2012 9:47 am 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
I think it can be done by making changes to gcc/config/i386/i386.c and gcc/config/i386/i386.h. There is no define for overriding the memory-model defined today, but it is possible to add one that does this. The relevant variable is ix86_cmodel. There is a conditional on MS_ABI today which overrides pic_flag and the memory model, so it is possible to add one to use the medium memory model in pic-mode.

Unfortunately, I just overwrote my source tree with tar -xf command on a renamed archive. :evil:


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Wed Dec 12, 2012 2:07 pm 
Offline
Member
Member

Joined: Wed Oct 01, 2008 1:55 pm
Posts: 3194
While I have found out how to build GCC in medium memory model, it doesn't seem to work. The compiler itself now builds and seems to work, but libgcc won't. One of the files generates errors (libgcc/config/i386/cpuinfo.c). The error is "error: inconsistent operand constraints in 'asm' __cpuid_count(7, 0, eax, ebx, ecx, edx);. It seems like the code is using 32-bit addressing when it should have used 64-bit addressing.

I'll analyse this further, and request patches for the problem (in addition to the patch for being able to build-in a default medium memory model into the compiler). Maybe providing this first will make it easier to get the rdos-patches accepted later. :mrgreen:


Top
 Profile  
 
 Post subject: Re: Building 64-bit GCC target for RDOS
PostPosted: Fri Dec 14, 2012 2:02 pm 
Offline
Member
Member
User avatar

Joined: Fri Jun 13, 2008 3:21 pm
Posts: 1700
Location: Cambridge, United Kingdom
You should be able to avoid having to build gcc -> newlib -> gcc by copying the contents of the newlib archive into the GCC directory. You can likewise overlay Binutils in this manner, to just have one (very large) build to do.

It's best to use the files from the latest package; the maintainers keep them in sync between binutils/gcc/newlib/gdb/etc


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 62 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 230 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group