MONO crosscompile mit Freetz

verstehe - Ich bin halt voller Euphorie, da ein Hello World schon funktioniert. Das macht Lust auf mehr. Auf die Gefahr, dass ich Prügel hier bekomme. Vielleicht klappt es mit dem Original AVM Image?
 
Ich hab mal gesucht, ob man einfach die ld-uClibc austauschen kann, aber es mangelt ein wenig an Suchergebnissen.

Eine einfache Möglichkeit ist mount bind.
Code:
mount --bind /tmp/ld-uClibc.so.0 /lib/ld-uClibc.so.0
Das hat auch den Vorteil/Nachteil, dass es beim nächsten Reboot weg ist. Man riskiert damit also nichts, und wenn es funktioniert, kann man es in den Autostart einbinden.
 
Gut das man es probiert hat: Wenn ich die ld-uClibc tausche kommt es zu einem Segmentation fault (könnte an der unterschiedlichen gcc version liegen).

Ich bastel mir wieder ein toolchain für das Cross-Compile :(.
 
Zuletzt bearbeitet:
Ok, ich habe das Problem dank gdb ergründet.

mono nutzt für manche Operationen kleine Funktionen, die in c geschrieben sind. Da die Toolchain ist mit fpu-emulation (msoft-float) erstellt wurden. Der JIT-Compiler geht aber von FPU-Operationen aus und erwartet die Ergebnisse in der FPU, die aber dummerweise vom GCC in der CPU abgelegt wurden.

Deswegen erhält man bei jeder Gleitkommakonvertierung einen NaN, oder was gerade zufällig in dem Register f0 steht.

Es sieht für mich so aus, als würde keine Programm auf der Box die CPU vollständig nutzen.

Die Toolchain kann man nicht ändern, also müssten alle Operation ersetzt werden. Das geht über eine kleine Änderung weit hinaus.

Ich weis auch noch nicht wie man vorgeht. FPU oder setzt man die Operationen in der CPU um?

Es müsste sich in Grenzen halten:
FCONV_TO_I8 double -> long
LCONV_TO_R8 long -> double
LCONV_TO_R4 long -> float
LCONV_TO_R8_UN ulong -> double
sind die Operationen die Simuliert werden, alle anderen Operationen sollten funktionieren?
 
Zuletzt bearbeitet:
Kann man vielleicht Mono anders kompilieren, so dass kein FPU verwendet wird?
 
Da die Toolchain ist mit fpu-emulation (msoft-float) erstellt wurden.
Der Grund dafür ist, dass die CPUs auf der Box keine FUP Hardware haben. Wenn die Hardware vorhanden wäre, würden wir nicht statt dessen die Software Emulation nutzen. Die normalen Aufgaben der AVM Boxen brauchen kaum eine FPU, daher ist es nachvollziehbar, dass AVM keine nutzt.
Es sieht für mich so aus, als würde keine Programm auf der Box die CPU vollständig nutzen.
Es gibt kaum ein Programm, das irgend eine CPU vollständig nutzt.
Wenn sich die Bemerkung aber auf Fließkommaoperationen bezieht, die funktionieren durchaus, aber eben nur in Emulation und daher langsamer. Das lässt sich aber mit der vorhandenen Hardware nicht vermeiden. Solange ein Programm in C geschrieben ist und konsistent die gleichen Optionen nutzt, gibt es da keine Probleme, weder mit der Berechnung noch Parameter Übergabe oder Rückgabewerte.
Die Toolchain kann man nicht ändern, also müssten alle Operation ersetzt werden. Das geht über eine kleine Änderung weit hinaus.
Die Toolchain kann man ändern, aber auch das hätte weitreichende Folgen.

FPU oder setzt man die Operationen in der CPU um?

Prinzipiell kann man FPU Anweisungen nutzen, diese werden jedoch auch emuliert und sind entsprechend langsam. Daher werden mit msoft-float die Parameter nicht in der emulierten FPU übergeben, sondern genauso wie die übrigen Parameter.

Sinnvoll wäre es, msoft-float Unterstützung in Mono einzubauen. Mit mhard-float wird die FPU Emulation nicht nur für die Berechnungen verwendet, sondern auch für Übergabe und Rückgabe von Werten, was zusätzlich Zeit kosten würde. Wo sind denn die von Dir angesprochenen Funktionen? In mini-mips.c habe ich nichts zu FCONV_TO_I8 usw. gefunden, bzw. nur auskommentierte Stellen.
 
@Ralf:
Danke das du noch mal das genauer erklärt hast. Ich hab mich gestern Nacht etwas kurz gefasst. Ich war erst einmal froh das Problem identifiziert zu haben.


msoft-float Plane ich derzeit auch ein. Ich muss nur die Register a0,a1,a2,a3 mit beladen und die Register v0, v1 mit abfragen, das macht der GCC ja auch so. Leider werden diese Befehle bei -Os wieder entfernt.
Denn ein Umbau nur dieser Funktion könnte noch wo anders Probleme ergeben, da einige Sachen in vorcompilierter Form in der Runtime enthalten sind.

mono_lconv_to_r8 befindet sich in der jit-icalls.c. Darf also nicht angefasst werden.

btw:
Es sieht für mich so aus, als würde keine Programm auf der Box die CPU vollständig nutzen.
Das ist das schöne an dem JIT, der prüft einige Prozessor-Features und passt sich entsprechend an... aber Schluss damit. Hatte mich hinreisen lassen.
 
msoft-float Plane ich derzeit auch ein. Ich muss nur die Register a0,a1,a2,a3 mit beladen und die Register v0, v1 mit abfragen, das macht der GCC ja auch so. Leider werden diese Befehle bei -Os wieder entfernt.
Welche Befehle werden entfernt? Wenn die Parameter verwendet werden, müssen sie aus den passenden Registern geladen werden, wenn auch nicht unbedingt am Anfang einer Funktion.
mono_lconv_to_r8 befindet sich in der jit-icalls.c.
Und wo wird der Aufruf dieser Funktion generiert?
 
In der mini-mips.c wird der Aufruf generiert, durch einen Aufruf der normalen Funktioncallgenerator.
 
N'Abend,

es war eine doofe Idee mit dem Problem heute Abend noch anzufangen ;). Bei mir scheint es aber jetzt zu funktionieren. Es werden nun ein paar zusätzliche Instruktionen erzeugt, die das SoftFloat-Verhalten bei der Parameterübergabe simulieren. Die Rückgabe war das kniffligste, aber ich hoffe mal ich hab nicht neue Fehler eingebaut. Mit float hab ich es noch nicht getestet.

Patch: Anhang anzeigen mono-3.4.0.patch.tar.gz

Gute Nacht
 
freut mich, dass Du einen Schritt weiter gekommen bist! Ich werde aber leider erst frühestens heute Abend zum Testen dazukommen...
 
Konnte es jetzt doch nicht erwarten und habe es schnell neu kompiliert. Bei mir wirft

TimeSpan ts = TimeSpan.FromMilliseconds(1000);
Console.WriteLine(ts.Seconds.ToString());

immer noch Fehler:

Unhandled Exception:
System.OverflowException: Outside range [MinValue,MaxValue]
at System.TimeSpan.From (Double value, Int64 tickMultiplicator) [0x00000] in <filename unknown>:0
at System.TimeSpan.FromMilliseconds (Double value) [0x00000] in <filename unknown>:0
at ConsoleApplication2.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.OverflowException: Outside range [MinValue,MaxValue]
at System.TimeSpan.From (Double value, Int64 tickMultiplicator) [0x00000] in <filename unknown>:0
at System.TimeSpan.FromMilliseconds (Double value) [0x00000] in <filename unknown>:0
at ConsoleApplication2.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
#


Vielleicht habe ich aber auch wegen Zeitmangel einen Fehler gemacht. Werd es am Abend nochmal im Detail testen....
 
Bei mir kommt eine 1.

Am besten Prüfe erst mal einfache Sachen z.B.

Code:
long l = 20000;
double d = (double)l;

bzw. einfache mathematische Operationen.
 
mkbundle, da ich die uCLibc statisch linken muss, da in meinen Freetz ne ziemlich alte enthalten ist.

Hat deine Box einen Mathematischen Coprozessor? Soll ja nicht immer vorhanden sein.
 
Ich habe eine FB 7390. Bin mir nicht sicher, was da alles eingebaut ist.

Ich habe nochmal ein wenig getestet und bekomme folgendes merkwürdiges Verhalten. Scheinbar hängt es mit der Übergabe von Parametern zusammen... Würdest Du Dir das nochmal ansehen?


Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            LongTest MaxValue2 = new LongTest(long.MaxValue);
            LongTest MinValue2 = new LongTest(long.MinValue);

            Console.WriteLine(MaxValue2.Ticks.ToString()); //  9223372036854775807
            Console.WriteLine(MinValue2.Ticks.ToString()); // -9223372036854775808
            Console.WriteLine(long.MaxValue.ToString());  //  9223372036854775807
            Console.WriteLine(long.MinValue.ToString());  // -9223372036854775808



            double value = 1000;
            Console.WriteLine(value < long.MinValue); //False
            Console.WriteLine(value > long.MaxValue); //False


            Console.WriteLine(value < MinValue2.Ticks); //False
            Console.WriteLine(value > MaxValue2.Ticks); //True <------------ Warum?
            Console.WriteLine( ((float) MaxValue2.Ticks).ToString()); // 0 <--------Warum?

        }

    }

    class LongTest
    {
        public long Ticks { get; set; }
        public LongTest(long l)
        {
            Ticks = l;
        }
    }
}
 
Code:
9223372036854775807
-9223372036854775808
9223372036854775807
-9223372036854775808
False
False
False
False
0
Das wird die Konvertierung long to float sein. Das eine True kann ich nicht nachvollziehen.
 
Bei der Konvertierung stimmt scheinbar was nicht. Da ist noch ein Fehler drin...
Das "True" wäre dann aber noch am ehesten richtig, wenn (float) MaxValue2.Ticks = 0, da
value > (float) MaxValue2.Ticks
also
1000 > 0
= true


Ich wollte es gerade mit mkbundle versuchen. Leider erstellt mir Dein Script immer x86 Binaries... Hast Du da noch einen Tipp?

Jetzt bin ich gerade dran Mono nochmal zu kompiliern. Diesmal mit den gleichen Flags wie in Deinem mkbundle Script. Vielleicht bringt das Erfolg

@EDIT: Neu kompilieren hat nichts gebracht, meine Ausgabe:
9223372036854775807
-9223372036854775808
9223372036854775807
-9223372036854775808
False
False
False
True
0
 
Zuletzt bearbeitet:
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.