Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I just managed to build my first 64-bit application for RDOS. It is 33k large, and it has the elf-64 format.
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.
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.
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.
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.
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.
There obviously is a bug in the base-address code, because GCC bootstrap fails if you setup TEXT_START_ADDRESS above 4G.
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.
Last edited by rdos on Thu Dec 06, 2012 10:53 am, edited 1 time in total.
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:
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
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.
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.
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.
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.
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.
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