User:Combuster/notepad

From OSDev.wiki
Revision as of 23:55, 8 December 2008 by Combuster (talk | contribs) (Forked out the mach64 piece)
Jump to navigation Jump to search

These are my notes from experience. PD code, No warranty etc (i mess up things more than once).

Porting the FreeBasic Runtime

To get past deprecated versions and everything, I updated my FB installation from 0.15 to 0.20(!) As a consequence, I got the updated library and since I couldn't be bothered to merge all the differences, I had a go from scratch. I decided afterwards to record the general process here.

starting off

  1. unpacked libfb-0.20b to a temp directory, copied the rtlib directory over to my workspace
  2. got rid of the automake garbage :)
  3. performed some shell tricks to get a list of c files into the directories Makefile, so that I only needed to add that bit of building rules
  4. integrated the stuff into the build system.

Well, to start things off, I decided to compile the first c file in the list to see where things got awry, and was greeted by several screens full of errors.

Shaddap, I'm developing an OS here O.o

Starting at the top to work things out, there was a nice #error message, telling me that the platform was unsupported. No duh. Edited fb.h and removed that silly statement.

Then came the garbage from the C library - wide character support was *not* enabled and FB can get pretty nasty over that. So I stripped the fb_unicode.h header, and all the system-specific stuff not available in freestanding land and ended up with fb_file.h fb_device.h fb_serial.h fb_thread and fb_printer.h commented out. Next I went down the other files and commented out the remaining declarations with wide characters.

Some remaining functions were found and removed, and at some point the first function compiled.

Getting to the bone

Obviously, I tried next to compile all parts of the runtime library, which obviously didn't like the fact that lots of pieces were disabled. And of course the missing OS support. Some 50% of the files refused compilation, and to test for sanity, I shoved the remaining stuff into a single binary to see what was actually working. Of course the linker protested and more files were disabled

After disabling 99% of the source files, making mental notes of what was needed, some basic memory moving stuff was working. most string functions were failing with a undefined reference to __fb_ctx, the array functions with error handling code.

__fb_ctx and fb_hInit()

after a nice grep I located the definition in libfb_init.c this file compiled, but didn't link because of an OS dependency to fb_hInit(), with a comment belonging to host specific initialisation.

Since I needed nothing that the C runtime already provided for me, I got away easy with a small support file.

#include "../fb.h"

void fb_hInit( void )
{
    return;
}

afterwards, most of the string functions could be enabled.

Error numbers

The other keystone to the language are the array functions. The required source file that went about this was libfb_error_getset.c, which would provide the calls, but refused to compile from scratch, due to a missing ERROR constant. Simply setting ERROR to a constant resulted in a missing definition, which was resolved by re-enabling fb_thread in fb.h which in turn (what else) gave trouble. After removing parts of an enum with more missing macro's, all that was left was again a depency to what appeared to be a host support function. This time dealing with thread local storage.

Since I didn't want to bother with the threading support, I added a stub that would fix the messages and do something useful. Basically it returns the error context for this specific thread.

#include "../fb.h"

FB_ERRORCTX __fb_errorctx;

FBCALL void *fb_TlsGetCtx (int index, int len )
{ 
    switch(index)
    {
        case FB_TLSKEY_ERROR:
            return(&__fb_errorctx);
            break;

        default:
            while(1);
    }
    
    while(1);
    return(NULL);
}

Since the ERROR macro made no sense, I changed that too adding this into fb_error.h (replacing the previous ERROR macro I put there):

#define ERROR FB_TLSKEY_ERROR

Afterwards, most array functions were operational, and some other random functions started working too. With runtime support for the two most used primitives, I decided to call it a day and commit the changes.


DIV test

originally devised to tell apart amd/intel/cyrix/whatever 486s and 386s that didn't have cpuid, this still works on current hardware. You can detect spoofs (emulators?) by verifying the div test signature with the expected one.

recent intels maintain all flags after DIV, as do bochs and qemu by default. cyrices clear most flags, AMDs set some and clear some.

PUSHFD
POP EAX
; either clear flags for first test, or set flags for second test. pick one:
; AND AX, (0xffff - 0x8D5)
; OR AX, 0x8D5
PUSH EAX
MOV AX, 5
MOV CL, 2
POPFD
DIV CL 
PUSHFD
POP EAX
AND EAX, 0x8D5
;AX contains signature

in 16-bit mode, use popf and ax instead of popfd and eax

results I've gathered:

CPU Div test with all flags clear Div test with all flags set
Intel 686 0x000 0x8D5
AMD K6-II 0x010 0x811
AMD Athlon64 0x010 0x811
Cyrix Cx6x86 / M1 0x000 0x801
Emulator Div test with all flags clear Div test with all flags set
Bochs 0x000 0x8D5
Qemu (without kqemu) 0x000 0x8D5

Still looking for information on the 386 and 486 generation...

Bochs messages

A list of messages and likely causes:

interrupt(): gate descriptor is not valid sys seg

You have not loaded an IDT, or the IDT is corrupt

interrupt(): SS selector null
  • You have no TSS
  • You haven't set SS0 / ESP0 in the TSS

HPPA

That big noisy RISC machine from HP. Oh well. Needs some patching to get a elf toolchain built.

apparently there are two file formats at work here: ELF and SOM. if you mix up those two you get no end of assembly messages (unknown pseudo-op .nsubspa etc). the following got me a successfully built gcc. I have not tested its actual operations for sanity. Just doccing it here so I can reproduce the results on a computer that's closer to my HPPA machine.

add to gcc/config.gcc

hppa-*-elf*)
	target_cpu_default="MASK_PA_11|MASK_NO_SPACE_REGS"
	tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h \
		 pa/pa-pro-end.h libgloss.h"
	tmake_file="pa/t-pro"
	use_collect2=yes
	gas=yes
	;;

run

export PREFIX=/usr/cross
export TARGET=hppa-elf
mkdir build-gcc-hppa
mkdir build-binutils-hppa
cd build-binutils-hppa
../binutils-x.x/configure --target=$TARGET --prefix=$PREFIX --disable-nls
make
make install
cd ..
export PATH=$PATH:/usr/cross/bin
cd build-gcc-hppa
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX --without-headers
            --disable-nls --with-newlib --enable-languages=c
make all-gcc
make install-gcc

works with binutils 2.17/gcc 4.2.2 fails on binutils 2.17/gcc 4.1.1

The 15 minutes spent trying to get palo (the opensource bootloader used with linux) to compile resulted in an asm error in crt0.s and several missing system headers (guess what, PA-RISC + LILO = PALO. linux.h missing. d'oh).

And that was one step out of the many that need be taken...