Software > Coding

GCC ohne MintLib

(1/2) > >>

mfro:

--- Zitat von: simonsunnyboy am Fr 17.05.2013, 16:17:34 ---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.

--- Ende Zitat ---

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.

simonsunnyboy:
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:

--- Code: ---#include <osbind.h>

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

--- Ende Code ---

Ich glaub, wenn ich dafür die nötige Compile- und Linksequenz kenne, dann kann ich mit einem gcc Kenntnisstand weiterdranarbeiten.

mfro:
Hier mal schnell was zusammengenagelt:

startup.S:

--- Code: --- .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

--- Ende Code ---

tst.c:

--- Code: ---#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;
}

--- Ende Code ---

Makefile:

--- Code: ---#

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

--- Ende Code ---

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.

simonsunnyboy:
Danke, das ist ein Startpunkt und wenigstens einmal dokumentiert. Mal schauen, wie weit ich damit komme.

Ausprobieren muss ich es noch in Ruhe....

simonsunnyboy:
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?

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln