atari-home.de - Foren

Software => Coding => Thema gestartet von: mfro am Sa 18.05.2013, 09:07:21

Titel: GCC ohne MintLib
Beitrag von: mfro 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.

Titel: Re: GCC ohne MintLib
Beitrag von: simonsunnyboy 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.
Titel: Re: GCC ohne MintLib
Beitrag von: mfro 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.
Titel: Re: GCC ohne MintLib
Beitrag von: simonsunnyboy 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....
Titel: Re: GCC ohne MintLib
Beitrag von: simonsunnyboy 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?
Titel: Re: GCC ohne MintLib
Beitrag von: mfro 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.
Titel: Re: GCC ohne MintLib
Beitrag von: simonsunnyboy 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