Autor Thema: GCC ohne MintLib  (Gelesen 49077 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline mfro

  • Benutzer
  • Beiträge: 1.640
GCC ohne MintLib
« am: Sa 18.05.2013, 09:07:21 »
Deswegen nehme ich AHCC und hinke mit "meiner" Lib halt Zeit bedingt hinterher. Zeit für Atari ist halt knapp....

Kann vllt einer von euch mal in einem separaten Thread beschreiben, mit welchem Ansatz man denn mit dem gcc eine eigene libc anfangen würde? Zugriff auf XBIOS, BIOS und GEMDOS wäre Minimalfunktionaliät. Wenn man die hat, kann der Rest aufgebaut werden.

Mein Problem wenn ich jetzt spontan die newlib portieren wollen würde, wäre wohl, daß die TOS Bindings als Grundlage fehlen, um die Lücken zu füllen.

Die TOS-Bindings brauchst Du nicht anzufassen. Die sind vollständig in Inline-Assembler in osbind.h bzw. mintbind.h und laufen ohne mintlib so gut wie mit.

Was Du brauchst, um die mintlib loszuwerden ist ganz wenig. Ein neuer Startup-Code, der nur die notwendigsten Dinge wie z.B. Mshrink() erledigt und dann _main() aufruft. Es wird noch eine (leere) Funktion __main() gebraucht, die vom Compiler aufgerufen wird.

Dann dein Programm mit -nostdlib übersetzen.

Bei komplexeren Programmen müssen - je nach Zielprozessor - wahrscheinlich noch ein paar _builtin-Funktionen geschrieben werden (die Integer-Multiplikationen _mulsi3()/_divsi3() z.B und ihre entsprechenden divxxx() - Gegenstücke. Wenn Du memcpy() verwenden willst, mußt Du's selber schreiben. Auf printf() und Konsorten mußt Du verzichten bzw. die auch nachbilden.

Ein einfaches "Hello World" kommt so mit weniger als 600 Bytes Programmgröße aus.

And remember: Beethoven wrote his first symphony in C

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: GCC ohne MintLib
« Antwort #1 am: Sa 18.05.2013, 14:52:43 »
Könntest Du vllt. eine ganz kurze Sequenz bringen, wie man ein entsprechendes .TOS baut und linkt, welches ohne die MintLib aber mit mit TOS-Bindings funktioniert und z.B. vom Gemdos kurz Cconws aufruft?

nehmen wir an, folgende kurze reguläre C main() soll zu hello.tos gebaut werden, der Code stehe in hello.c:
#include <osbind.h>

int main(int argc, char **argv)
{
  Cconws("Hallo GEMDOS!\n");
  return 0;
}

Ich glaub, wenn ich dafür die nötige Compile- und Linksequenz kenne, dann kann ich mit einem gcc Kenntnisstand weiterdranarbeiten.
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Offline mfro

  • Benutzer
  • Beiträge: 1.640
Re: GCC ohne MintLib
« Antwort #2 am: Sa 18.05.2013, 17:37:05 »
Hier mal schnell was zusammengenagelt:

startup.S:
.equ BASEPAGE_SIZE,0x100
.equ STACK_SIZE,0x1000

.text

start:
move.l 4(sp),a5 | address to basepage
move.l 0x0c(a5),d0 | length of text segment
add.l 0x14(a5),d0 | length of data segment
add.l 0x1c(a5),d0 | length of bss segment
add.l #STACK_SIZE+BASEPAGE_SIZE,d0 | length of stackpointer+basepage
move.l a5,d1 | address to basepage
add.l d0,d1 | end of program
and.l #0xfffffff0,d1 | align stack
move.l d1,sp | new stackspace

move.l d0,-(sp) | mshrink()
move.l a5,-(sp)
clr.w -(sp)
move.w #0x4a,-(sp)
trap #1
lea.l 12(sp),sp


jsr _main

exit:
clr.w -(sp)
trap #1

.bss

_basepage: ds.l 1
_program_length:
ds.l 1

.end

tst.c:
#include <osbind.h>

void __main()
{
}


int main(int argc, char *argv[])
{
(void) Cconws("Hello world\r\n");

(void) Cconws("\r\n<press any key to return to desktop>\r\n");
Cconin();

return 0;
}

Makefile:
#

TOOLCHAIN_PREFIX=m68k-atari-mint-
CC=$(TOOLCHAIN_PREFIX)gcc

UNAME := $(shell uname)
ifeq ($(UNAME),Linux)
PREFIX=m68k-atari-mint
HATARI=hatari
else
PREFIX=/opt/cross-mint/m68k-atari-mint
HATARI=/usr/local/bin/hatari
endif

CFLAGS=-mcpu=68000\
-Os\
-fomit-frame-pointer \
-Wall\
-mshort\
-nostdlib

TST=tst
APP=$(TST).prg

all: $(APP)

SOURCES=startup.S $(TST).c

OBJECTS=$(SOURCES:.c=.o)

$(APP): $(OBJECTS) depend
$(CC) $(CFLAGS) $(OBJECTS) -o $(APP)
m68k-atari-mint-strip $(APP)

.PHONY clean:
- rm -rf *.o depend tst.prg

depend: $(SOURCES)
$(CC) $(CFLAGS) $(INCLUDE) -M $(SOURCES) tst.c > depend

test: tst.prg
$(HATARI) -D --tos ../emutos/etos512k.img -m --bios-intercept --cpuclock 32 --machine ste --cpulevel 3 --vdi true --vdi-planes 1 \
--vdi-width 800 --vdi-height 600 -d .




ifneq (clean,$(MAKECMDGOALS))
-include depend
endif

Das fertige Programm hat 439 Bytes (das Makefile 863 ;) ), tut aber, was Du wolltest (wartet zusätzlich sogar noch auf einen Tastendruck).

Features (wie z.B. gefülltes argv[] und argc oder gar envp[]) darf man dafür nicht erwarten, aber hübsch klein ist es.
And remember: Beethoven wrote his first symphony in C

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: GCC ohne MintLib
« Antwort #3 am: Sa 18.05.2013, 18:27:29 »
Danke, das ist ein Startpunkt und wenigstens einmal dokumentiert. Mal schauen, wie weit ich damit komme.

Ausprobieren muss ich es noch in Ruhe....
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: GCC ohne MintLib
« Antwort #4 am: Fr 01.11.2013, 17:33:09 »
Ich bin heute mal zum Austesten gekommen, und es läuft super!

Was mich wundert ist die zusätzliche leere Funktion void __main(void)
Diese wird zur Linkzeit benötigt, wird aber wohl garnicht aufgerufen. Was ist da der Trick?

Ferner wäre es imho sinnvoll, diese als eigentliche main zu haben. Wenn man keine Kommandozeilenargumente verwenden kann (was für diesen Usecase kleinstes Binary nicht stört), dann braucht man diese doch auch eigentlich nicht an die Funktion zu übergeben?
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Offline mfro

  • Benutzer
  • Beiträge: 1.640
Re: GCC ohne MintLib
« Antwort #5 am: Fr 01.11.2013, 17:52:00 »
Ich bin heute mal zum Austesten gekommen, und es läuft super!

Was mich wundert ist die zusätzliche leere Funktion void __main(void)
Diese wird zur Linkzeit benötigt, wird aber wohl garnicht aufgerufen. Was ist da der Trick?

Ferner wäre es imho sinnvoll, diese als eigentliche main zu haben. Wenn man keine Kommandozeilenargumente verwenden kann (was für diesen Usecase kleinstes Binary nicht stört), dann braucht man diese doch auch eigentlich nicht an die Funktion zu übergeben?

Den Aufruf von __main() generiert gcc selbst (als erstes Statement in _main()): versuch' mal, was passiert, wenn Du die Funktion weglässt. Das Ding wird man nicht los (macht aber m.E. nix und man kann es leicht in einer Library verstecken - s. libcmini).

Ich glaube das hat was mit C++ zu tun - gcc würde in __main() wohl die globalen Konstruktoren initialisieren.
And remember: Beethoven wrote his first symphony in C

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: GCC ohne MintLib
« Antwort #6 am: Di 15.04.2014, 19:38:44 »
Ich habe mal etwas rumgebastelt, wenn man das startup.s erweitert, muss man die leere ___main() nicht mehr im C Code mitanbieten:

.globl ___main

___main:
rts
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee