PDA

View Full Version : [C# / X# ] Cosmos - C# Open Source Managed Operating System


fano
03-07-2016, 14:41
Ciao a tutti!

Questo è il thread ufficiale di Cosmos un nuovo sistema operativo scritto in C# e in X# (il nostro assembler di alto livello).

Cosmos può essere considerata la versione Open Source dei sistema operativi di ricerca della Microsoft Singolarity e Midori: un sistema operativo scritto in C# con integrato il runtime .NET.

Come per Linux il termine sistema operativo è improrio Cosmos è un kernel che può essere esteso (letteralmente) dallo sviluppatore per ottenere un sistema operativo completo.
Attualmente quello che si ottiene è un sistema operativo a linea di comando come il DOS: non aspettatevi subito di vedere il Linux del futuro o il nuovo Windows!

Ci sono due parti diciamo complicate del progetto:


Benché il 99% di .NET sia stato scritto in C# ci sono punti in cui è chiamato codice nativo che alla fine va ad effettuare chiamate al kernel di Windows (o dell'OS sottostante). In tutti questi casi è necessario scrivere un "plug" per sostituire la chiamata C++ con codice C#. Un esempio banale Console.WriteLine() alla fine per scrivere sulla Console chiama... la printf()!
IL2CPU il nostro compilatore che converte codice IL in assembler. Alcuni opcode o non sono implementati o non funzionano correttamente. Abbiamo creato un nostro linguaggio (!) chiamato X# per semplificare la scrittura dell'Assembler, ma è sempre Assembler... X86 per giunta!


Mentre con IL2CPU probabilmente non ci dovrete andare a sbattere aspettatevi invece di dover scrivere dei "plug" anche per cose apparentemente banali tipo getHashCode() (ma è davvero banale ;) ? Come si fa a fare l'hash code di un enum? Vi ricordo che per un enum potete definire il tipo sottostante... un enum potrebbe essere anche un long! Ma voi volete fare solo myEnum.gatHashCode(), vero? C# deve usare Reflection per calcolare quell'hashcode!).

Differenze tra Cosmos e un Sistema Operativo classico:


In Cosmos non esiste una separazione hardware tra la memoria del Kernel e quella dei processi: c'è un solo grosso spazio di memoria a cui tutti possono accedere! La sicurezza viene garantita dal runtime stesso quindi per scrivere su un file non c'è nessuna syscall al kernel: il processo chiamando le opportune funzione della classe FileStream scrive effettivamente sul File (Zero Copy I/O!)
In Cosmos ci sono i Ring, ma non sono quello che credete! Sono implementati in software non in hardware, la scopo è però più o meno lo stesso (un processo a livello utente non ha accesso diretto all'hardware)
In Cosmos non può MAI per nessun motivo girare codice NON verificabile / non managed! Sì non potrete mai usare C o C++ su Cosmos questo taglia fuori tutta la tecnologia dei 50 anni precedenti! Sì sono passati 50 anni: è il momento di ricominciare da capo :D
La domanda del secolo: che tipo di kernel è Cosmos? E' un kernel monolitico? Adesso sicuramente visto che anche il Kernel è indistinguibile dall'applicazione! E' un exokernel? Certo visto che l'applicazione scrive direttamente sul file ed il kernel si occupa solo di allocare la memoria e fare da "mutex" tra le risorse! E' un microkernel? No, per ora no (ma in futuro lo sarà). Forse dovremo inventare una categoria nuova? Wikipedia classifica Midori come "language based OS" per ora accontentiamoci di questa classificazione.


Quindi perché il thread è aperto qui e non in "Sistemi Operativi"? Semplice non abbiamo bisogno di utenti, ma di sviluppatori! Le conoscenze richieste sono C# (ovviamente), ma si deve essere in grado di scrivere anche driver e in alcuni rari casi è richiesto anche di conoscere assembler.

Come scritto in firma se volete collaborare allo sviluppo unitevi alla chat!
Ovviamente avendo un thread in italiano di molte cose potremo parlarne anche qui...

GTKM
04-07-2016, 06:57
Avendo intenzione di contribuire allo sviluppo a partire dalle prossime settimane, mi iscrivo! :D

fano
04-07-2016, 08:42
Vista la mia conoscenza di C# mi iscriverei (conosco anche C, e marginalmente C++, ma non Assembler).

Però avrei bisogno di avere qualche info in più sul progetto:
- da dove è partita l'idea?


Sicuramente l'idea deriva molto dai SO di ricerca della Microsoft Singularity e Midori.
Kudzu (uno degli sviluppatori) ha questo sogno che vuole un giorno portare su Cosmos:

http://www.codeproject.com/Articles/11064/Mobile-Agents-Software-on-the-move


- quali obiettivi si prefigge?


Uno dei target sono i sistemi embedded, Internet of Things, VM (hyperV o Azure). Per questi scenari non serve una GUI, ma basta la linea di comandi quindi sono più "semplici" da realizzare.

C'è già un parziale supporto a VGA, quindi volendo qualcosa di grafico potete anche farlo con la grafica del 1980 (320x240@256 colori). IMHO non ne vale la pena molto più interessante fare un driver VBE che permetterebbe di arrivare anche 1920 x 1080!

Con la GUI uno potrebbe pensare ad altri scenari:


Mediacenter
SO per telefoni
In generale applicazioni "kiosk" varie per esempio bancomat
Si anche un SO desktop :p


Questa è la mia idea per il SO del futuro "OcAlot" (leggi Ocelot) a me piacerebbe fare in modo che il SO sia in grado sempre di avere la possibilità una sorta di GUI anche quando è a linea di comando senza che il codice sia cambiato se non c'è la modalità VGA appare una TUI come quelle del DOS "Commander", se c'è la VGA invece apparire una GUI via via più bella a seconda di risoluzione / colori.
Potremmo chiamarlo "Contuum everywhere" :p


- quanto è estesa la community?


Beh per ora siamo pochini... 4 nei giorni buoni! Questo è il nostro più grosso problema!
Se riesco a portare altre 2 finiamo per essere la maggioranza noi Italiani :p


- diventerà davvero una valida alternativa ai S.O. esistenti?


Questa è una domanda da un milioni di €! Noi del team ovviamente ci speriamo, ma prevedere il futuro è sempre difficile. Di certo la licenza (MIT) è migliori di quella di Linux quindi se qualche corporation se ne interessa...


- quanto è esteso al momento il suo utilizzo?

Attualmente il SO è ancora in fase Alpha quindi... 4 persone (noi stessi :D).

ingframin
04-07-2016, 14:46
Sicuramente l'idea deriva molto dai SO di ricerca della Microsoft Singularity e Midori.
Kudzu (uno degli sviluppatori) ha questo sogno che vuole un giorno portare su Cosmos:

http://www.codeproject.com/Articles/11064/Mobile-Agents-Software-on-the-move



Uno dei target sono i sistemi embedded, Internet of Things, VM (hyperV o Azure). Per questi scenari non serve una GUI, ma basta la linea di comandi quindi sono più "semplici" da realizzare.


Mi sa che non ne sapete tanto di sistemi embedded...
Il fatto che manchi la gui non significa che siano più semplici da realizzare, anzi...
Hanno tutta una serie di problematiche che cozzano contro l'idea di un sistema operativo del genere.
Prima tra tutti la scarsità di memoria!
Aggiungo poi che tipicamente i sistemi embedded hanno bisogno di esecuzione real time, molto spesso hard real time... Come la gestite questa cosa con un sistema operativo totalmente managed in cui il programmatore non ha possibilità di gestire manualmente la memoria? Almeno fornite l'opzione di bloccare il garbage collector?
Senza contare il fatto che usando un sistema totalmente managed scartate a priori tutta una serie di ottimizzazioni che non è più possibile fare vista la natura dinamica del C#.

Forsa ha senso come sistema desktop, non capisco però perché proibire a priori l'uso di programmi compilati staticamente con C e C++.

Se pensate ad android:
- Dalvik compila il bytecode in codice nativo
- I processori ARM hanno un'unità chiamata jazelle che esegue nativamente il bytecode java.

È figa come idea e sicuramente un ottimo esercizio didattico, ma secondo me finisce come questo:
https://en.wikipedia.org/wiki/JavaOS

fano
04-07-2016, 19:27
Mi sa che non ne sapete tanto di sistemi embedded...
Il fatto che manchi la gui non significa che siano più semplici da realizzare, anzi...


Il mio più semplice era inteso che se devi fare un sistema operativo desktop
devi avere almeno dei driver per la GPU decenti (esiste VBE, ma senza accellerazione hardware soprattutto se ti trovi con un ARM a 300 MHz non vai da nessuna parte!), poi devi studiare le API per disegnare tutti i componenti lato applicazione e visto che partiamo da C# ci si aspetta di poter usare XAML per disegnare la GUI...


Hanno tutta una serie di problematiche che cozzano contro l'idea di un sistema operativo del genere.
Prima tra tutti la scarsità di memoria!
Aggiungo poi che tipicamente i sistemi embedded hanno bisogno di esecuzione real time, molto spesso hard real time... Come la gestite questa cosa con un sistema operativo totalmente managed in cui il programmatore non ha possibilità di gestire manualmente la memoria?


Dipende da come è implementato il GC ci sono versioni meno invasive ed altre di più e poi il nostro compilatore (come quello di Midori) tra le variabili ottimizzazioni farà anche "Stack Escape Analysis" cercando il più possibile di allocare gli oggetti nello stack... come fanno alcune versioni di JVM.


Almeno fornite l'opzione di bloccare il garbage collector?


E' una caso prevista da .NET:
http://stackoverflow.com/questions/6005865/prevent-net-garbage-collection-for-short-period-of-time

quindi si potrà avere anche nel nostro caso.

Ma è sconsigliato dalla Microsoft secondo me se ti trovi ad usare quello hai codice scritto "male" non è colpa di C#, ma tua!


Senza contare il fatto che usando un sistema totalmente managed scartate a priori tutta una serie di ottimizzazioni che non è più possibile fare vista la natura dinamica del C#.


Cosa intendi con "natura dinamica"? C# non è mica javascript ha tipizazzione forte! Parli forse del "dynamic" aggiunto di recente per supportare Iron Python dentro .NET?

Comunque per essere chiari il runtime .NET e tutta l'applicazione in Cosmos viene compilata in assembler (AOT) non c'è nessuna macchina virtuale in Cosmos non nel senso classico! Certo c'è il Garbage Collector, ci sono le eccezioni, gli array hanno i bound check[1], ecc...

Per mia esperienza diretta il codice C scritto bene prevede che ogni funzione abbia il check dei parametri di input (cosa che in C# fai meglio con eccezioni e contratti) e le stringhe con dimensione a "caso" sullo stack sono cause di bug infiniti. Alla fine è "managed"... a mano, ma se non lo "maneggi" ti esplode in faccia, quindi...

La sfida è questa "safe native code":
http://joeduffyblog.com/2015/12/19/safe-native-code/
(è già stato fatto: può essere fatto di nuovo!).


Forsa ha senso come sistema desktop, non capisco però perché proibire a priori l'uso di programmi compilati staticamente con C e C++.


Per due motivi:

1. Il kernel dovrà essere compilato per l'architettura target (ovvio visto che tutti gli IL opcode, i driver, ecc... dovranno essere per il nuovo target), ma le applicazioni no! E' C# "compile once, run everywhere"
2. Se apri la porta a codice "non verificabile" apri la porta agli hacker: uno sbordamento al punto giusto e bam mi sovrascrivi il kernel! Poi non voglio vedere schifezze come OpenSSL che per essere super veloce era scritto in C e così violava lo scopo per cui era scritta: la sicurezza! Uno se vuol farsi del male può usare C++/CLI comunque, ma nella versione "pure CLR" ovviamente.


Se pensate ad android:
- Dalvik compila il bytecode in codice nativo
- I processori ARM hanno un'unità chiamata jazelle che esegue nativamente il bytecode java.


Anche noi compiliamo codice nativo ;)
Ma questo non significa che Google ha perso tutti i vantaggi di un linguaggio Managed: JAVA c'è sempre: non c'è più la JVM!
Jazelle mi risulta non più presente negli ultimi processori ARM.


È figa come idea e sicuramente un ottimo esercizio didattico, ma secondo me finisce come questo:
https://en.wikipedia.org/wiki/JavaOS


E' presto per dirlo! JavaOS era troppo avanti per i tempi IMHO ed è per questo che è fallito...

[1] Sempre che il compilatore durante la fase di ottimizzazione non decida di rimuovere il check come in questo caso banale:


for (i = 0; i < array.len; ++)
c = arr[i]; // for garauntes array is always on bound!

fano
04-07-2016, 21:27
Occhio che il discorso di OcAlot è il lontano futuro quando saremo ricchi (come Linus Torvalds e Richard Stallman :D) e famosi (come Bill Gates).
Per il momento manco son sicuro del nome, mi piace l'idea di un Ocelot ninja su un Tirannosauro, ma mi sa che è un'immagine che ho già visto da qualche parte :D

Allora su cosa stiamo lavorando al momento:

- Garbage Collector (RAT l'hanno chiamato... si è una sigla, ma non è una cosa troppo nerdosa tipo Linux IS Not Unix)
- Filesystem abbiamo una classe generica da cui abbiamo derivato l'implementazione della FAT16 / FAT32 (FAT64 / extFat temiamo sia sottoposta a copyright! E no, noi non violiamo il copyright altrui). Sopra a questa sono implementate (pluggate) tutti le classi di I/O tipiche di .NET così dal punto di vista dell'utente (sei tu che scrivi il Kernel! Non l'utente come s'intende di solito) nulla cambia. Ci sono ancora del lavoro da fare per esempio delete non so se funziona davvero. Anche aggiungere test a questo kernel è molto apprezzato: https://github.com/CosmosOS/Cosmos/blob/master/Tests/Cosmos.Kernel.Tests.Fat/Kernel.cs
L'idea è che finito il supporto a FAT si derivi dalla classe VFSManager e si realizzi un altro FS o uno nostro o un altro Open Source (non so quello di BeOS BeFs? Quello dell'Amiga? ISO, UDF? Se siete maligni anche Ext3...) questo dimostrebbe che la classe è "generica" e non fa assunzioni derivate da FAT
- Base Class Library di questa parte mi sto occupando io, in particolare sto lavorando sui Floating Point: alcune operazioni (cast) non funzionavano davvero / non erano implementate, ora molte lo sono! Anche in questo caso aggiungere test a questo kernel è molto apprezzato:
https://github.com/CosmosOS/Cosmos/tree/master/Tests/Cosmos.Compiler.Tests.Bcl
- Zork Demo: l'intenzione è far vedere Zork che gira su Cosmos a qualche fiera dell'Open Source. Non ho capito se funziona o no... so solo che dopo che ce l'avevano messo dentro il mio codice non compilava perché "magicamente" dipendeva da Zork (?) :Prrr:

Quindi dove iniziare? Da qui direi:
https://github.com/CosmosOS/Cosmos/wiki/How-to-install-Cosmos
(lasciate perdere l'User Kit è troppo vecchio ormai partite usando sempre il DevKit)

se l'installazione va a buon fine (il .bat può rompere le palle all'AntiVirus, ma non preoccupatevi è tutto "normale") provate il kernel Guess se gira siete a cavallo. A quel punto puoi provare a installare l'UserKit (con il .bat) nei sorgenti e creare il tuo kernel: è uno dei modi per trovare che qualcosa manca / funziona male!
Poi vieni in chat, presentati e vedrai che qualcosa da farti fare lo troviamo sempre.

Per esempio io volevo che il mio OS assomigliasse a questo:

https://www.c64-wiki.com/images/c/c9/Einschaltmeldung_C64.jpg

ma non riuscivo a selezionare il background / foreground (lo faceva ma in modo "strano") e il cursore non lampeggiava.
Son finito a guardare documentazione della VGA in modalità "BIOS" degli anni '70... ma ora il mio blu è come il C=64 e OcAlot e sempre "READY" e lampeggia impaziente pure! Però per esempio come fare da C# ad avere "xxx bytes free"? Ecco per esempio altro spazio in cui si potrebbe lavorare...

Un altra "demo" interessante dopo avere il driver della VGA funzionante potrebbe essere un emulatore di NES tipo portare questo:
https://sourceforge.net/projects/mynes/

ma potrebbe essere prematuro per ora: se la BCL ha dei "buchi" ed ovviamente vorrai anche l'audio a quel punto vero?

Ah un altra cosa che ho dimenticato se conoscete linguaggi "esotici" della famiglia .NET potete usarli senza problemi per scrivere il vostro OS per esempio se vi piace VB.Net nessuno vi impedisce di usarlo (ma non per il kernel quello è solo in C# / X#) ed anzi è un test interessante pure quello! Magari VB.NET o F# usano opcodes particolari che C# non usa?

||ElChE||88
04-07-2016, 22:32
Aggiungo poi che tipicamente i sistemi embedded hanno bisogno di esecuzione real time, molto spesso hard real time...
Per embedded credo intenda i router, le smart tv e roba simile su cui gira Linux assolutamente non in real time. Dubito vogliano fare concorrenza a VxWorks, ThreadX e compagni.

cdimauro
05-07-2016, 06:05
Concordo. Ma è anche vero che è molto presto per pensare a soluzioni real-time.
L'idea è che finito il supporto a FAT si derivi dalla classe VFSManager e si realizzi un altro FS o uno nostro o un altro Open Source (non so quello di BeOS BeFs? Quello dell'Amiga? ISO, UDF? Se siete maligni anche Ext3...) questo dimostrebbe che la classe è "generica" e non fa assunzioni derivate da FAT
Quello dell'Amiga lasciatelo perdere. Almeno per il momento, vi serve un filesystem "serio", come NTFS, BeFS, etc. che supporti journaling, metadati, dimensioni di partizioni e/o file generosi, nomi di file lunghi, compressione, criptazione, ecc.

Per il resto, evitate di sprecare tempo nel portare o scrivere emulatori et similia: c'è taaaaaanto lavoro da fare ancora a livello di kernel, driver, librerie.

fano
05-07-2016, 08:37
Concordo. Ma è anche vero che è molto presto per pensare a soluzioni real-time.


Vedremo in futuro cosa riusciremo a fare :D


Quello dell'Amiga lasciatelo perdere. Almeno per il momento, vi serve un filesystem "serio", come NTFS, BeFS, etc. che supporti journaling, metadati, dimensioni di partizioni e/o file generosi, nomi di file lunghi, compressione, criptazione, ecc.


NTFS temo abbia il copyright per una cosa totalmente legale non potrebbe far parte di Cosmos, ma un OS da esso derivato previo pagamento di licenza alla Microsoft potrebbe implementarlo. La licenza è MIT quindi chiunque può forkare Cosmos e creare un "prodotto" se vuole: per esempio un Mediacenter tipo le cinesate che ora sono basate su Android o i ricevitori sat "evoluti" oggi basati su Linux / Enigma.

Forse dopo FAT ha senso provare ISO per leggere CD / DVD / montare immagini ISO?

BeFS comunque mi stuzzica parecchio! Be OS era un sistema operativo coi fiocchi vorrei che il mio OS fosse organizzato in quel modo...


Per il resto, evitate di sprecare tempo nel portare o scrivere emulatori et similia: c'è taaaaaanto lavoro da fare ancora a livello di kernel, driver, librerie.


Quella dell'emulatore era un'idea per una possibile applicazione di Cosmos: un OS con NES integrato: fai il boot e ti trovi dentro un "NES" virtuale che però assomiglia il più possibile al vero NES a partire dal fatto che il boot dure pochi secondi :D
Un po' per dare uno "stimolo" per fare il NES ci vuole un driver della VGA decente e quindi prima scrivi quello, poi fai anche l'audio e poi ti accorgi che ti serve altro..,

Alla fine cosa è un OS? Ciò che fa girare le applicazioni quindi tentare di far andare un'applicazione e ad aggiungere pezzi all'OS potrebbe essere un approccio... un po' strano forse... come dicono quelli che inventano in termini della fava? Top to bottom?

cdimauro
05-07-2016, 21:34
NTFS temo abbia il copyright per una cosa totalmente legale non potrebbe far parte di Cosmos,
I brevetti scadono in 17-20 anni, se non ricordo male, per cui NTFS dovrebbe essere ormai implementabile liberamente.
ma un OS da esso derivato previo pagamento di licenza alla Microsoft potrebbe implementarlo.
Non credo che un'implementazione in un progetto open source sviluppato a titolo puramente gratuito possa rientrare nelle mire di Microsoft.

La licenza, eventualmente, la dovrebbe pagare chi USA quell'implementazione di NTFS in qualche prodotto commerciale.
La licenza è MIT quindi chiunque può forkare Cosmos e creare un "prodotto" se vuole: per esempio un Mediacenter tipo le cinesate che ora sono basate su Android o i ricevitori sat "evoluti" oggi basati su Linux / Enigma.
Meno male che avete usato una licenza realmente libera. :)
Forse dopo FAT ha senso provare ISO per leggere CD / DVD / montare immagini ISO?
Assolutamente sì.
BeFS comunque mi stuzzica parecchio! Be OS era un sistema operativo coi fiocchi vorrei che il mio OS fosse organizzato in quel modo...
Mi pare che BeFS fosse un po' complicato da implementare. Comunque se cerchi in giro c'è il libro di uno degli sviluppatori, che ha descritto completamente questo filesystem. Il PDF dovrebbe essere completamente gratuito.
Quella dell'emulatore era un'idea per una possibile applicazione di Cosmos: un OS con NES integrato: fai il boot e ti trovi dentro un "NES" virtuale che però assomiglia il più possibile al vero NES a partire dal fatto che il boot dure pochi secondi :D
Un po' per dare uno "stimolo" per fare il NES ci vuole un driver della VGA decente e quindi prima scrivi quello, poi fai anche l'audio e poi ti accorgi che ti serve altro..,
Ecco, appunto: intanto pensate a un driver VESA decente, che è il minimo indispensabile. E poi l'audio AC'97 come minimo.
Alla fine cosa è un OS? Ciò che fa girare le applicazioni quindi tentare di far andare un'applicazione e ad aggiungere pezzi all'OS potrebbe essere un approccio... un po' strano forse... come dicono quelli che inventano in termini della fava? Top to bottom?
Pensateci dopo avere realizzare un minimo d'infrastruttura: kernel + filesystem (possibilmente journaled) + driver VESA + driver AC'97 + driver Ethernet sono il minimo indispensabile.

fano
06-07-2016, 08:32
I brevetti scadono in 17-20 anni, se non ricordo male, per cui NTFS dovrebbe essere ormai implementabile liberamente.


Anche se la Microsoft lo usa ancora nei suoi OS? Non è che la avranno rinnovato il brevetto?
Non lo avevano menato a Google e ai produttori di macchine fotografiche perché usavano la FAT sulle chiavette? Eppure FAT avrà quasi 30 anni :D


Non credo che un'implementazione in un progetto open source sviluppato a titolo puramente gratuito possa rientrare nelle mire di Microsoft.

La licenza, eventualmente, la dovrebbe pagare chi USA quell'implementazione di NTFS in qualche prodotto commerciale.


Sì ero a quello che mi riferivo! Quindi secondo te è possibile implemetarla nel kernel mettendo una sorta di clausola "se utilizzi NTFS in un prodotto commerciale devi pagare la licenza"? Le licenze sono un po' un casino...


Meno male che avete usato una licenza realmente libera. :)


Sì la licenza MIT è credo la cosa più importante, la GPL è così libera che non è libera affatto! Se hai "donato" i sorgenti devo poterne fare ciò che voglio...


Mi pare che BeFS fosse un po' complicato da implementare. Comunque se cerchi in giro c'è il libro di uno degli sviluppatori, che ha descritto completamente questo filesystem. Il PDF dovrebbe essere completamente gratuito.


Sì l'avevo letto! BeFS era davvero al passo coi tempi un database filesystem in cui le ricerche di file duravano millesecondi: certo erano semplicemente una query in un DB! Fu probabilmente uno dei primi filesystem ad usare gli attributi almeno in maniera così estesa per esempio per sistemare in modo sensato una collezione di MP3 in un OS classico hai bisogno di un database (così puoi fare le ricerche / creare cartelle virtuali per nome canzone, nome dell'autore, anno di produzione...) con BeFS tutte queste informazioni sono attributi del file! Sì anni dopo inventarono ID3Tag, ma in BeOS era integrato nell'OS e potevi farlo per qualunque tipo di file!
L'ideale per un Mediacenter!


Ecco, appunto: intanto pensate a un driver VESA decente, che è il minimo indispensabile. E poi l'audio AC'97 come minimo.

Pensateci dopo avere realizzare un minimo d'infrastruttura: kernel + filesystem (possibilmente journaled) + driver VESA + driver AC'97 + driver Ethernet sono il minimo indispensabile.

Per la milestone 1 (SO a linea di comando) probabilmente dopo il filesystem la cosa che sarà da implementare è la rete e far vedere che si può connettere via telnet / ssh.

cdimauro
06-07-2016, 21:18
Anche se la Microsoft lo usa ancora nei suoi OS? Non è che la avranno rinnovato il brevetto?
No, i brevetti non si possono rinnovare/allungare: dopo 17-20 anni terminano, e chiunque può implementarli liberamente senza dover dare un centesimo all'autore.
Non lo avevano menato a Google e ai produttori di macchine fotografiche perché usavano la FAT sulle chiavette? Eppure FAT avrà quasi 30 anni :D
Ma FAT32/VFAT no. ;)

Secondo te perché giusto qualche anno fa Microsoft ha presentato exFAT? Per farlo diffondere e fargli prendere il posto di FAT32, i cui brevetti sono ormai scaduti o quasi. exFAT = nuovi brevetti = nuovo periodo di tempo in cui Microsoft può sfruttarli e farsi pagare. :D
Sì ero a quello che mi riferivo! Quindi secondo te è possibile implemetarla nel kernel mettendo una sorta di clausola "se utilizzi NTFS in un prodotto commerciale devi pagare la licenza"? Le licenze sono un po' un casino...
Certamente. Guarda gli altri progetti open source, come FFMPEG o x264, che implementano codec blindatissimi con una caterva di brevetti e, soprattutto, un consorzio pronto a chiedere lo scalpo di chi li usa: nessuno ha fatto causa agli autori di questi progetti. ;)
Sì la licenza MIT è credo la cosa più importante, la GPL è così libera che non è libera affatto! Se hai "donato" i sorgenti devo poterne fare ciò che voglio...
Assolutamente d'accordo.
Sì l'avevo letto! BeFS era davvero al passo coi tempi un database filesystem in cui le ricerche di file duravano millesecondi: certo erano semplicemente una query in un DB! Fu probabilmente uno dei primi filesystem ad usare gli attributi almeno in maniera così estesa per esempio per sistemare in modo sensato una collezione di MP3 in un OS classico hai bisogno di un database (così puoi fare le ricerche / creare cartelle virtuali per nome canzone, nome dell'autore, anno di produzione...) con BeFS tutte queste informazioni sono attributi del file! Sì anni dopo inventarono ID3Tag, ma in BeOS era integrato nell'OS e potevi farlo per qualunque tipo di file!
L'ideale per un Mediacenter!
Però bisogna anche supportarlo, per cui devi costruirci sopra un'infrastruttura / GUI / CLI adeguata.
Per la milestone 1 (SO a linea di comando) probabilmente dopo il filesystem la cosa che sarà da implementare è la rete e far vedere che si può connettere via telnet / ssh.
Benissimo.

tomminno
07-07-2016, 14:58
Ricordo di aver seguito Singularity al tempo e c'erano alcuni punti che non mi sono mai stati chiari.

Si parlava di implementare la sicurezza via software. Possibile che sia più veloce e sicura di quella implementata in hardware?

Se non ricordo male Microsoft aveva realizzato strumenti di sviluppo appositi (Bartok?).
Come si scrive il runtime .Net usando .Net stesso? :fagiano:

C'erano molti limiti pratici alle sandbox: niente dynamic loading (eseguibili monolitici?), niente Jit.
Oltre a non poterci girare Java (e tutti gli altri linguaggi), non ci gira nemmeno un programma .Net standard, ma solo un suo subset. Il tutto per raggiungere quale obiettivo?

fano
07-07-2016, 18:13
Ricordo di aver seguito Singularity al tempo e c'erano alcuni punti che non mi sono mai stati chiari.

Si parlava di implementare la sicurezza via software. Possibile che sia più veloce e sicura di quella implementata in hardware?


Vedi il fatto è che in un SO classico la "sicurezza" è implementata con il fatto che il kernel e tutto i processi vivono in aree di memoria separate e quando per esempio un programma utente deve scrivere su un file avvengono le seguenti operazioni:


1. Il processo chiama una funzione per esempio la classifica write() del C
Viene triggerato un software interrupt al kernel. Questo in Linux si traduce in una syscall
Il buffer utente viene copiato e ci si sposta nello spazio di memoria del kernel
Il kernel - a sua volta - chiama una funzione di basso livello che l'equivalente della write dal punto di vista del driver dell'HDD
La memoria del kernel viene di nuovo copiata per scrivere i dati sul disco
Il disco smette di scrivere (magari anche nella cache) e ritorno la risposta al kernel: tipicamente 0 per successo, 1 per errore. Anche nel giro inverso quello '0' è copiato minimo 3 volte!


Un processo in Singulary è un "Software Isolated Process" ovvero è NON è un processo, ma un thread che dal punto di vista della CPU ha gli stessi privilegi del kernel (certo è un pezzo del kernel!), il "kernel" espone l'equivalente dello File.Write() come funzione pubblica e quindi il nostro processo può usarla direttamente! Visto che siamo nello stesso spazio di memoria il buffer non viene copiato 3 volta, ma è lo stesso identico buffer che ha passato l'utente che è scritto sul disco. Non ci sono "software interrupt" o cose "esotiche" semplici chiamate a metodi!

Altro esempio visto che Singularity e Midori erano Microkernel (Cosmos lo sarà... un giorno!) è tipico in quei tipi di kernel che 2 processi si scambino messaggi e questo perché un microkernel funzioni correttamente deve essere veloce, se devi passare dal kernel ogni volta sei fritto: Singularity lo bypassava completamente e scriveva gli oggetti direttamente nella coda dell'altro processo (che è sempre un thread ricordiamocelo!).

Quindi cosa vuol dire che la sicurezza è via software? Che non puoi chiamare un metodo privato di un altro oggetto, andare a sbordare nella sua memoria, ecc... tutte cose che .NET garantisce di "suo".

In Cosmos abbia un ulteriore strato sempre software che è chiamato "ring" il ring 0 è quello più a basso livello dove persino assembler può vivere (satana!), il livello utente mi pare sia 4, sì l'utente è il SO che implementa il kernel, l'utente "classico" potrà avere privilegi ancora minori (ring 5!).


Se non ricordo male Microsoft aveva realizzato strumenti di sviluppo appositi (Bartok?).
Come si scrive il runtime .Net usando .Net stesso? :fagiano:


Lo so che fa venir mal di testa, ma come il C è scritto in C... .NET è scritto in C# (anche quello classico che è installato su Windows) solo piccole parti sono in C++ o in assembler. Bartok in realtà veniva dopo ed aveva il compito di trasformare l'IL in assembler. In Cosmos noi facciamo lo stesso con IL2CPU.


C'erano molti limiti pratici alle sandbox: niente dynamic loading (eseguibili monolitici?), niente Jit.


Del dynamic loading non so perché non fosse presente in Singularity, il JIT proprio perché non si voleva avere la VM o meglio il kernel e la VM .NET condividevano lo stesso spazio di memoria e giravano come codice nativo.

Comunque credo che Midori fosse andato molto più avanti ad un certo punto danno l'impressione che girasse Windows (!) parlano di Skype e persino di un browser! Peccato che il codice probabilmente giace in qualche soffitta e non vogliano renderlo pubblico...


Oltre a non poterci girare Java (e tutti gli altri linguaggi), non ci gira nemmeno un programma .Net standard, ma solo un suo subset. Il tutto per raggiungere quale obiettivo?

Cosmos in questo sarà diverso (non guardare quello di ora in cui gira uno ed un solo programma: non abbiamo ancora implementato i thread :Prrr: ) un'applicazione scritta in qualunque linguaggio .NET (quindi C#, VB.NET, F#) girerà su Cosmos in un modo simile a NGEN:


L'applicazione è compilata con Visual Studio: è una normale applicazione .NET che gira su Windows e pure su Linux (con Mono)
Viene copiata su un sistema Cosmos
Al primo run (o durante l'installazione) viene compilato per il codice nativo della macchina su cui sta girando. Visto che ora "sappiamo" tutto della CPU possiamo - volendo - ottimizzare per SSE, AVX, NEO, ecc...
Il compilato o viene salvato in una qualche directory "bin-cache" o in maniera più elegante dentro l'eseguibile stesso (se non sbaglio è ciò che fa NGEN / .NET Native)
L'applicazione gira senza problemi come ha fatto su Windows e su Linux
Le volte successive - ovviamente - l'applicazione parte più velocemente visto che è già stata compilata


Se il dispositivo è sfigato (per esempio è un telefono) si può fare come fa la Microsoft nel suo store con .NET Native: lo sviluppatore consegna l'applicazione in formato .NET alla Microsoft che provvede a pre-compilarla ed è la versione compilata che l'utente installa sul suo telefonino.

In realtà basta avere come target IL e tutti i linguaggi potranno girare su Cosmos:

1. Java potrebbe pure girarci con l'aiuto di IKVM basta installare su Cosmos l'IL ottenuto
2. Python è OK basta usare IronPython
3. Javascript dovrebbe esistere js.net
4. ... beh tutti questi qui: https://en.wikipedia.org/wiki/List_of_CLI_languages

C'è persino C++ nella versione C++/CLI, ma lì è per modo di dire visto che sarebbe la versione completamente managed e non credo che nessun codice C++/CLI sia completamente managed: è stato creato proprio per essere il ponte tra .NET e il codice nativo. Scrivere un'applicazione in C++/CLI invece che in C# mi pare un po' una tortura forse l'unico vantaggio sarebbe la deallocazione della memoria più controllabile?

cdimauro
08-07-2016, 05:14
Microkernel senza distinzione fra kernel e userspace (immagino che giri tutto in ring-0 a questo punto) mi ricorda il s.o. dell'Amiga. :sofico:

Ma questa volta fatto bene, visto che quest'ultimo è ben noto per le Guru Meditation. :p

fano
08-07-2016, 08:19
Sì non è diverso solo che appunto il linguaggio su cui è basato è C# non C, quindi, appunto niente "guru meditation" :D

Anche VxWorks non credo sia molto diverso, comunque...

pabloski
08-07-2016, 09:59
L'idea alla base di Singularity mi sembrava buona all'epoca, ma poi incappai in questo post http://web.archive.org/web/20150318180616/http://ok-labs.com/blog/entry/singularity-vs-l4-microkernel-performance/

I punti principali sollevati dall'autore sono:

1. il codice della sola VM di Singularity e' piu' grande di quello di tutto L4
2. i runtime checks finiscono per pesare piu' dei mode switch

Con l'avanzare della tecnologia dei microprocessori, gli switch hardware sono diventati sempre piu' rapidi, il che ha reso ancora piu' inutile il non uso della modalita' protetta.

tomminno
08-07-2016, 16:58
Quando si parla di compilare in nativo in questo caso si parla di un qualcosa tipo MSIL o di vero e proprio codice macchina?
Nel secondo caso, se tutto gira in ring 0 cosa impedisce di andare ad eseguire istruzioni x86 privilegiate e fare danni in giro?

Per quanto riguarda la scrittura del .Net in C# (che è un linguaggio .Net) come si gestisce deterministicamente la memoria in C#?
Perchè il runtime gestisce la memoria in maniera deterministica, differentemente da un programma scritto per girare nel runtime.

Infine come si fa da C# ad accedere ai registri? Se sei un OS l'accesso ai registri è pane quotidiano. A maggior ragione se devi fare tutti i controlli sui permessi di accesso lato software senza basarti sulle funzionalità hardware.

fano
08-07-2016, 21:06
Quando si parla di compilare in nativo in questo caso si parla di un qualcosa tipo MSIL o di vero e proprio codice macchina?


Codice macchina, puro e semplice!


Nel secondo caso, se tutto gira in ring 0 cosa impedisce di andare ad eseguire istruzioni x86 privilegiate e fare danni in giro?


I livelli (che sono un'implementazione software dei ring) non ti permetteranno di fare questo:

https://github.com/CosmosOS/Cosmos/blob/master/Docs/Kernel/Levels.md

un'applicazione sarà sempre a livello 3 e quindi non potrà chiamare nessuna istruzione privilegiata (non puoi scrivere codice assembler a livello 3 e nemmeno codice unsafe probabilmente).
Certo uno "monello" potrebbe scrivere un SO "malvagio" che è un virus, ma questo cosa ti garantisce che una distribuzione Linux non possa fare lo stesso?


Per quanto riguarda la scrittura del .Net in C# (che è un linguaggio .Net) come si gestisce deterministicamente la memoria in C#?


Perché dovresti gestirla "deterministicamente" c'è il garbage collector una nostra versione (non quello classico di .NET).


Perchè il runtime gestisce la memoria in maniera deterministica, differentemente da un programma scritto per girare nel runtime.


Beh nei casi in cui sia necessario anche C# permette di allocare nello stack usando stackalloc.


Infine come si fa da C# ad accedere ai registri? Se sei un OS l'accesso ai registri è pane quotidiano. A maggior ragione se devi fare tutti i controlli sui permessi di accesso lato software senza basarti sulle funzionalità hardware.

Infatti tra quadre ho messo anche X# che il nostro High Level assembler per X86:

https://en.wikipedia.org/wiki/X_Sharp

qui siamo molto a basso livello (debug su porta seriale):
https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Debug.DebugStub/SerialIO.xs

dobbiamo ancora studiare come embeddare X# dentro C# per ora facciamo così, ma non ci soddisfa affatto:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.IL2CPU/IL/Add.cs

(tutto quello che inizia con XS è codice X# dentro C#)

probabilmente in futuro useremo qualcosa di simile a GCC:


inline X# = {
ESI = 12345 // assign 12345 to ESI
EDX = #constantForEDX // assign #ConstantForEDX to EDX
EAX = EBX // move EBX to EAX => mov ebx, eax
EAX-- // decrement EAX => dec eax
EAX++ // increment EAX => inc eax
EAX + 2 // add 2 to eax => add eax, 2
EAX - $80 // subtract 0x80 from eax => sub eax, 0x80
BX * CX // multiply BX by CX => mul cx -- division, multiplication and modulo should preserve registers
CX / BX // divide CX by BX => div bx
CX mod BX // remainder of CX/BX to BX => div bx
}


Per esempio quando ho implementato Conv.R.Un non mi ha soddisfatto come dichiarare le costanti questo dovrebbe essere più semplice, molto più semplice di come è ora... è anche molto difficile passare un valore da C# a X#.
Abbiamo ancora un po' da lavorare su questo.

cdimauro
09-07-2016, 06:46
Personalmente trovo l'inline di GCC molto più semplice di X#.
L'idea alla base di Singularity mi sembrava buona all'epoca, ma poi incappai in questo post http://web.archive.org/web/20150318180616/http://ok-labs.com/blog/entry/singularity-vs-l4-microkernel-performance/

I punti principali sollevati dall'autore sono:

1. il codice della sola VM di Singularity e' piu' grande di quello di tutto L4
2. i runtime checks finiscono per pesare piu' dei mode switch

Con l'avanzare della tecnologia dei microprocessori, gli switch hardware sono diventati sempre piu' rapidi, il che ha reso ancora piu' inutile il non uso della modalita' protetta.
Ma l'obiettivo di progetti come Singularity e Cosmos non è strettamente quello di evitare context switch e/o l'uso della modalità protetta.

Invocare velocemente un'API che è disponibile solo in kernel mode, o usare la modalità protetta, non ti mette al riparo da buffer overflow et similia, che possono succedere ugualmente.

Comunque il link che hai postato è interessante, ma non mi è chiaro come abbiano fatto i test per la spedizione di messaggi.

fano
10-07-2016, 13:42
Personalmente trovo l'inline di GCC molto più semplice di X#.


L'idea è di astrarre (nascondere se preferisci) le stranezze dell'architettura x86 il più possibile in modo che "venga" naturale scriverlo insieme a C#.
Per esempio per scrivere un valore in un registro non viene fatta una "move" (da dove?) ma viene usato l'operatore =, mentre nella versione XS si usa il metodo "Set" che oggettivamente ha più senso di Move. Però sì c'è ancora molto da lavorare su X# e - ovviamente - si accettano suggerimenti.


Ma l'obiettivo di progetti come Singularity e Cosmos non è strettamente quello di evitare context switch e/o l'uso della modalità protetta.

Invocare velocemente un'API che è disponibile solo in kernel mode, o usare la modalità protetta, non ti mette al riparo da buffer overflow et similia, che possono succedere ugualmente.


Non ho ben capito questa parte, in un OS come Singularity o Cosmos essendo basati su .NET buffer overflow non possono succedere: c'è un vero tipo String (non un array di caratteri la cui lunghezza il linguaggio non persiste con un "pietoso" '\0' in fondo che le stesse funzione di libc non rispettano), gli array hanno sempre il bound checking ecc...

Certo puoi fare "casini" con unsafe e X# (in assembler puoi corrompere lo stack in un attimo e tanti saluti al kernel :Prrr: ), ma quello sarà codice - molto poco e specifico - relegato al livello 0.

Se qualcuno "osa" scrivere una libreria SSL in Cosmos e si mette a fare "truschi" con l'assembler perché deve essere veloce beh allora abbiamo fallito l'obbiettivo :cry:


Comunque il link che hai postato è interessante, ma non mi è chiaro come abbiano fatto i test per la spedizione di messaggi.

Io rilancio con questo:
http://joeduffyblog.com/2015/11/19/asynchronous-everything/

in particolare quoto questo paragrafo:

It was pretty common to be running the Midori system at 100% CPU utilization, because it was doing useful stuff, which is pretty rare on PCs and traditional apps.

Cioè normalmente quando la CPU è al 100% siamo piene di rotelle / palle / clessidre, vero? In Midori, no! Era al 100%, ma il sistema era sempre responsivo... non esisteva alcun IDLE :eek:

Comunque oggi si continua con i lavori: Conv.U8!

fano
10-07-2016, 14:21
Mah mi chiedo, ma i float / double servono davvero a qualcosa?

double aDouble = 9223372036854775849d;
ulong value = (ulong)aDouble;
Print(value);
9223372036854775808

Cioè ma sta facendo casino anche a convertire un numero intero? E il C fa uguale quindi non è qualche casino nostro...

Chissà se usando le SSE su un sistema a 64 bit avrebbe funzionato meglio?
Vado a cercarmi un Linux a 64 bit...

cdimauro
10-07-2016, 19:04
L'idea è di astrarre (nascondere se preferisci) le stranezze dell'architettura x86 il più possibile in modo che "venga" naturale scriverlo insieme a C#.
Non devi mica portarti dietro tutte le istruzioni legacy: quelle al 99,999999% non le usa più nessun compilatore da non so quanti anni. :D

Ma il resto, sì. E presta particolare attenzione a certe istruzioni di stringa, perché sebbene sian da tempo considerate legacy, negli ultimi anni sono state notevolmente potenziate nei processori Intel, tanto da essere preferite alle equivalenti che fanno uso di istruzioni SIMD per riempire o copiare la memoria.
Per esempio per scrivere un valore in un registro non viene fatta una "move" (da dove?) ma viene usato l'operatore =, mentre nella versione XS si usa il metodo "Set" che oggettivamente ha più senso di Move. Però sì c'è ancora molto da lavorare su X# e - ovviamente - si accettano suggerimenti.
Preferisco l'operatore di uguaglianza (o al limite il := di pascaliana memoria) per la move, di qualunque genere essa sia (registri general purpose, di controllo, debug, ecc.).

IMO dovreste partire proprio da come funziona l'inline di GCC, ma cercate di semplificare al massimo il tutto. Ad esempio evitare di usare il # in
EDX = #constantForEDX
non ne vedo il motivo.
Non ho ben capito questa parte, in un OS come Singularity o Cosmos essendo basati su .NET buffer overflow non possono succedere: c'è un vero tipo String (non un array di caratteri la cui lunghezza il linguaggio non persiste con un "pietoso" '\0' in fondo che le stesse funzione di libc non rispettano), gli array hanno sempre il bound checking ecc...
Non mi riferivo a Singularity o Cosmos in quel contesto, ma al microkernel L4, che lascia la possibilità di buffer overflow, mentre i primi due no.
Certo puoi fare "casini" con unsafe e X# (in assembler puoi corrompere lo stack in un attimo e tanti saluti al kernel :Prrr: ), ma quello sarà codice - molto poco e specifico - relegato al livello 0.
Ecco, questa è una cosa che dovete chiarire, perché se lasciate tanta libertà lì, allora tutto il castello di "sicurezza" che avete costruito a livello utente può rischiare di crollare.
Se qualcuno "osa" scrivere una libreria SSL in Cosmos e si mette a fare "truschi" con l'assembler perché deve essere veloce beh allora abbiamo fallito l'obbiettivo :cry:
Se gli darete la possibilità, lo faranno.
Io rilancio con questo:
http://joeduffyblog.com/2015/11/19/asynchronous-everything/

in particolare quoto questo paragrafo:

It was pretty common to be running the Midori system at 100% CPU utilization, because it was doing useful stuff, which is pretty rare on PCs and traditional apps.

Cioè normalmente quando la CPU è al 100% siamo piene di rotelle / palle / clessidre, vero? In Midori, no! Era al 100%, ma il sistema era sempre responsivo... non esisteva alcun IDLE :eek:

Comunque oggi si continua con i lavori: Conv.U8!
Meglio, perché l'articolo è troppo lungo e non ho tempo di leggerlo.
Mah mi chiedo, ma i float / double servono davvero a qualcosa?
Certo che sì.
double aDouble = 9223372036854775849d;
ulong value = (ulong)aDouble;
Print(value);
9223372036854775808

Cioè ma sta facendo casino anche a convertire un numero intero? E il C fa uguale quindi non è qualche casino nostro...
I double non possono essere precisi, tranne per un sottoinsieme di valori interi.
Chissà se usando le SSE su un sistema a 64 bit avrebbe funzionato meglio?
Vado a cercarmi un Linux a 64 bit...
Non credo che le SSE c'entri qualcosa, e nemmeno i 64 bit.

fano
10-07-2016, 19:47
Non devi mica portarti dietro tutte le istruzioni legacy: quelle al 99,999999% non le usa più nessun compilatore da non so quanti anni. :D

Ma il resto, sì. E presta particolare attenzione a certe istruzioni di stringa, perché sebbene sian da tempo considerate legacy, negli ultimi anni sono state notevolmente potenziate nei processori Intel, tanto da essere preferite alle equivalenti che fanno uso di istruzioni SIMD per riempire o copiare la memoria.

Preferisco l'operatore di uguaglianza (o al limite il := di pascaliana memoria) per la move, di qualunque genere essa sia (registri general purpose, di controllo, debug, ecc.).

IMO dovreste partire proprio da come funziona l'inline di GCC, ma cercate di semplificare al massimo il tutto. Ad esempio evitare di usare il # in
EDX = #constantForEDX
non ne vedo il motivo.


In effetti quel #value non lo capisco nemmeno io... ne chiederò il senso!
Certo che a tendere dovremo trovare un modo per usare "=" con X# embeddato in C#, il codice con XS.func() è un passo intermedio... dobbiamo riuscire a fare come LINQ scrivere codice in un altro linguaggio dentro C#!

Un altra cosa che va fatta ASAP è come dichiarare le variabili dentro assembler...
Per ora mi tocca fare così:

DataMembers.Add(new DataMember(@"__doublesignbit", 0x8000000000000000));


e poi per usarla:


XS.LiteralCode(@"pxor XMM0, [__floatsignbit]");


invece vorrei poter almeno fare:


XS.PXOR(XMM0, "__floatsignbit", destinationIsIndirect: true);


anche se il modo veramente "splendido" sarebbe:


XS.PXOR(XMM0, 0x80000000, destinationIsIndirect: true);



Non mi riferivo a Singularity o Cosmos in quel contesto, ma al microkernel L4, che lascia la possibilità di buffer overflow, mentre i primi due no.


Ah OK! E' L4 che è scritto in C che fa buffer overflow ovviamente...


Ecco, questa è una cosa che dovete chiarire, perché se lasciate tanta libertà lì, allora tutto il castello di "sicurezza" che avete costruito a livello utente può rischiare di crollare.

Se gli darete la possibilità, lo faranno.


Io credo che a livello utente (livello 4) solo codice managed deve poter girare infondo unsafe ha molto meno senso che in normale C# visto che non ci sarà mai la necessità di fare p/invoke visto che il kernel stesso è scritto in C# anche il discorso "velocità" dovrebbe decadere se riusciamo a fare un compilatore super-ottimizzante come quello di Midori...

X# / Assembler deve ovviamente esistere solo a livello 0 per quelle poche cose che ne necessitano (per esempio scrivere sulle porte hardware della VGA? Far spegnere la CPU con l'istruzione HLT?). E' chiaro che come accade con C# unsafe ci si costruisce tutta una classe intorno che rende usabile la cosa...


Meglio, perché l'articolo è troppo lungo e non ho tempo di leggerlo.


Sì Joe Duffy non è parco di parole, ma l'articolo è davvero interessante (come tutto il resto del suo Blog). Da proprio l'impressione che gli piaccia il suo lavoro: beato lui :D


Certo che sì.

I double non possono essere precisi, tranne per un sottoinsieme di valori interi.


Io sapevo che erano imprecisi sui valori con la virgola, ma speravo che almeno gli interi si salvassero...

Capisci il mio unit test ora non ha molto senso io metto in un double un valore intero "preciso" per me essere umano, lo converto in ulong ed ottengo un numero diverso?
La mia Assertion è false, ma dovrebbe essere true!

Hanno senso per disegnare grafica forse? Dove in fondo è meglio disegnare velocemente e se poi i punti non si toccano si spera nell'aliasing o nell'occhio umano difettoso?

Se io volessi fare una calcolatrice per esempio non potrei usarli (0.2 * 3 != 0.6?), per l'uso che ne faccio io sul lavoro non hanno senso per me rappresentano valori monetari e a volte devo calcolare il cambio e con i double vengono numeri "causali" dopo già la III cifra decimale, con _Decimal32 e il decimal di C# ho valori corretti!
(Lo stesso caso dell'unit test passa senza problemi usando il tipo decimal infatti).

A proposito Intel ha pensato di accelerare il tipo decimal con IBM ha fatto per i suoi sistemi con CPU Power? Questo è l'unico difetto i decimal sono molto più lenti dei double perché sono implementati in software...


Non credo che le SSE c'entri qualcosa, e nemmeno i 64 bit.

Sì hai ragione anche usando SSE su un sistema a 64 bit non cambia nulla: ho provato per togliermi il dubbio con un'orrida Ubuntu a 64 Bit ed il risultato è lo stesso... un numero sbagliato :cry:

Altra cosa che ho notato come differenza tra SSE e x87: SSE non ha un'istruzione diretta per negare un float / double, mentre x87 aveva fchs. Nulla di complicato da "simulare" con SSE basta infatti fare uno XOR con -0.0 (ovvero 0x800....) e il segno "flippa", però perché non hanno implementato tutto in modo che potesse davvero sostituire x87?
Perché non c'è un modo diretto per operare sugli Int64 con SSE su x86, mentre con x87 sì? Perché non ci sono le funzioni trigonometriche in SSE?

||ElChE||88
11-07-2016, 00:04
Io sapevo che erano imprecisi sui valori con la virgola, ma speravo che almeno gli interi si salvassero...
Come fa un float a 32 bit a rappresentare tutti gli interi a 32 bit? Non resta più spazio per la parte frazionale.
Hanno senso per disegnare grafica forse? Dove in fondo è meglio disegnare velocemente e se poi i punti non si toccano si spera nell'aliasing o nell'occhio umano difettoso?
Molto, perché hanno ottime prestazioni ma soprattutto occupano poco spazio. La precisione limitata va presa in considerazione, ma è un compromesso accettabile; come per la CPU, anche per la GPU un collo di bottiglia molto comune è l'accesso alla memoria.

cdimauro
11-07-2016, 06:26
In effetti quel #value non lo capisco nemmeno io... ne chiederò il senso!
Certo che a tendere dovremo trovare un modo per usare "=" con X# embeddato in C#, il codice con XS.func() è un passo intermedio... dobbiamo riuscire a fare come LINQ scrivere codice in un altro linguaggio dentro C#!
Ma non potete introdurre niente di simile a GCC?
Un altra cosa che va fatta ASAP è come dichiarare le variabili dentro assembler...
Per ora mi tocca fare così:

DataMembers.Add(new DataMember(@"__doublesignbit", 0x8000000000000000));


e poi per usarla:


XS.LiteralCode(@"pxor XMM0, [__floatsignbit]");


invece vorrei poter almeno fare:


XS.PXOR(XMM0, "__floatsignbit", destinationIsIndirect: true);


anche se il modo veramente "splendido" sarebbe:


XS.PXOR(XMM0, 0x80000000, destinationIsIndirect: true);

Va bene che ormai sono arrugginito con l'assembly, ma se dovessi scrivere questi papiri ogni volta per una sola istruzione o dichiarazione, mi passerebbe la voglia di scrivere roba di X#.

Trovate un'altra soluzione/sintassi.
Io credo che a livello utente (livello 4) solo codice managed deve poter girare infondo unsafe ha molto meno senso che in normale C# visto che non ci sarà mai la necessità di fare p/invoke visto che il kernel stesso è scritto in C# anche il discorso "velocità" dovrebbe decadere se riusciamo a fare un compilatore super-ottimizzante come quello di Midori...
Personalmente non tendo a fidarmi molto delle promesse di realizzare compilatori super ottimizzanti. Basti vedere quello che è successo a Intel/HP con EPIC/Itanium.
X# / Assembler deve ovviamente esistere solo a livello 0 per quelle poche cose che ne necessitano (per esempio scrivere sulle porte hardware della VGA? Far spegnere la CPU con l'istruzione HLT?). E' chiaro che come accade con C# unsafe ci si costruisce tutta una classe intorno che rende usabile la cosa...
OK, questo è chiaro, ma... chi può scrivere questa roba? Perché lasciando una porta aperta sta tranquillo che qualcuno malizioso l'attraversa.

Per il resto, pensate di far girare qualunque cosa nel ring-0 del processore, visto che le applicazioni / codice utente dovrebbero essere del tutto "safe"?

Perché in linea teorica non vi servirebbe dividere il codice in kernel e user mode, per quanto hai detto finora, ed evitare un paio di context switch fra le due modalità fa sempre comodo in termini di velocità.
A proposito Intel ha pensato di accelerare il tipo decimal con IBM ha fatto per i suoi sistemi con CPU Power? Questo è l'unico difetto i decimal sono molto più lenti dei double perché sono implementati in software...
No. Tra l'altro ho visto che il decimal di .NET è a 128 bit: è troppo grande per poter esser gestito agevolmente. Normalmente i tipi decimal usati in ambito finanziario in engine SQL et similia usano valori interi a 64 bit, e hanno una parte fissa decimale (esempio: 4 cifre), per cui fanno uso di moltiplicazioni e divisioni con valori fissi, e sono abbastanza gestibili da un processore a 64 bit convenzionale.

Ma un decimal a 128 bit complica notevolmente le cose. Non capisco perché Microsoft non ne abbia fornito una versione "single"/64-bit e una "double"/128 bit.

Comunque non conosco l'implementazione di IBM, ma Intel ha introdotto alcune istruzioni per eseguire più agevolmente somme e moltiplicazioni a precisione elevata, che dovrebbero aiutare per i decimal a 128 bit. Ma rimarranno sempre molto più lenti da gestire.
Altra cosa che ho notato come differenza tra SSE e x87: SSE non ha un'istruzione diretta per negare un float / double, mentre x87 aveva fchs. Nulla di complicato da "simulare" con SSE basta infatti fare uno XOR con -0.0 (ovvero 0x800....) e il segno "flippa", però perché non hanno implementato tutto in modo che potesse davvero sostituire x87?
Perché non c'è un modo diretto per operare sugli Int64 con SSE su x86, mentre con x87 sì? Perché non ci sono le funzioni trigonometriche in SSE?
Perché x87 è un'FPU regolare & completa, mentre SSE è un'unità SIMD, per cui è orientata ad altro tipo di calcolo, e il focus è rappresentato dai single e double, mentre i tipi interi c'è molto meno spazio (in particolare per quelli a 64 bit).

Nel corso del tempo sono state introdotte nuove istruzioni che in parte colmano il gap, ma mancano ancora diverse corse, e... te le devi emulare.

Le nuove AVX-512 che arriveranno con Cannonlake (ma per settore server saranno disponibili già con Skylake) hanno delle estensioni (solo per i processori che le implementano) che ampliano le possibilità di manipolazione degli interi, ma adesso non ricordo quali migliorie siano state apportate.

In ogni caso non penso che abbiate voglia di scrivere già adesso il backend per AVX-512. :D

Purtroppo con le SSE dovete arrangiarvi in qualche modo.

tomminno
11-07-2016, 13:42
Codice macchina, puro e semplice!



I livelli (che sono un'implementazione software dei ring) non ti permetteranno di fare questo:

https://github.com/CosmosOS/Cosmos/blob/master/Docs/Kernel/Levels.md

un'applicazione sarà sempre a livello 3 e quindi non potrà chiamare nessuna istruzione privilegiata (non puoi scrivere codice assembler a livello 3 e nemmeno codice unsafe probabilmente).
Certo uno "monello" potrebbe scrivere un SO "malvagio" che è un virus, ma questo cosa ti garantisce che una distribuzione Linux non possa fare lo stesso?


Si parla sempre di controlli a monte della compilazione, ma una volta compilato se l'eseguibile viene modificato, chi lo controlla?
Quali controlli esegue l'OS e come, sulle istruzioni eseguite dai programmi? Non essendoci più le trap dovute ai ring hardware, mi chiedo come faccia l'OS ad intercettare chiamate privilegiate.
Mi pare assurdo fare un nuovo OS orientato alla sicurezza che poi cade come un castello di carte se qualcuno modifica a mano un eseguibile.


Perché dovresti gestirla "deterministicamente" c'è il garbage collector una nostra versione (non quello classico di .NET).


Il GC con cosa è scritto? Se parliamo di runtime scritto in C#, del runtime fa parte anche il GC.


Beh nei casi in cui sia necessario anche C# permette di allocare nello stack usando stackalloc.


Io parlavo proprio della gestione dell'heap. Lo stack comunque è molto limitato generalmente come dimensioni.
Infine stackalloc non è unsafe?

fano
11-07-2016, 14:21
Si parla sempre di controlli a monte della compilazione, ma una volta compilato se l'eseguibile viene modificato, chi lo controlla?


Cito dal documento postato sui livelli:

Since Cosmos can control execution and rebuild its compiler and recompile all code at any time, Cosmos can be much more flexible and most restrictions can be enforced at compile or installation time rather than the need to perform such CPU checks in live CPU code.

Quindi al momento dell'installazione quando - come ho già detto - il codice è ancora in formato IL viene verificato che l'applicazione che gira a livello utente non abbia al suo interno codice che non possa eseguire (per esempio codice unsafe, assembler o anche normale codice C#, ma che fa cosa che si è deciso di black listare...).
Una volta che ci si è assicurati di questo si crea la versione nativa che andrà scritta da qualche parte (dentro l'eseguibile stesso?) e non più scrivibile.


Quali controlli esegue l'OS e come, sulle istruzioni eseguite dai programmi? Non essendoci più le trap dovute ai ring hardware, mi chiedo come faccia l'OS ad intercettare chiamate privilegiate.
Mi pare assurdo fare un nuovo OS orientato alla sicurezza che poi cade come un castello di carte se qualcuno modifica a mano un eseguibile.


Potrebbe forse essere ideato un sistema di anti-tampering? Non lo so per esempio una volta create l'immagine binaria salvarsi l'MD5SUM / hashcode da qualche parte e prima di eseguire il programma verificare che corrisponda?

Tu cosa proponi?


Il GC con cosa è scritto? Se parliamo di runtime scritto in C#, del runtime fa parte anche il GC.


Il GC è scritto in C#, non so molto di quella parte, ma c'è un momento in cui Cosmos parte ed esegue la sequenza di istruzioni in assembler che tutti gli OS hanno sempre eseguito (modalità reale 16 Bit, 64 KB di RAM, ...) poi parte praticamente subito la "macchina virtuale" / "esecutore" C# e quindi il GC inizia a funzionare insieme a tutto il resto del runtime: il codice di Cosmos è normale codice C# dal punto di vista di chi lo scrive gli oggetti sono allocati sull'heap, c'è il garbage collector, ecc...


Io parlavo proprio della gestione dell'heap. Lo stack comunque è molto limitato generalmente come dimensioni.
Infine stackalloc non è unsafe?


Sì stackalloc è unsafe, ma a livello 0 (la parte core del Kernel) è ammesso che possa esistere codice unsafe questo è il codice che dovrebbe gestire l'heap io non ci capisco molto, ma come vedi è scritto in C# per quanto appunto unsafe:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Core.Memory/Heap.cs

tomminno
12-07-2016, 13:57
Cito dal documento postato sui livelli:

Since Cosmos can control execution and rebuild its compiler and recompile all code at any time, Cosmos can be much more flexible and most restrictions can be enforced at compile or installation time rather than the need to perform such CPU checks in live CPU code.

Quindi al momento dell'installazione quando - come ho già detto - il codice è ancora in formato IL viene verificato che l'applicazione che gira a livello utente non abbia al suo interno codice che non possa eseguire (per esempio codice unsafe, assembler o anche normale codice C#, ma che fa cosa che si è deciso di black listare...).
Una volta che ci si è assicurati di questo si crea la versione nativa che andrà scritta da qualche parte (dentro l'eseguibile stesso?) e non più scrivibile.


Quindi il codice è MSIL non codice macchina, il codice macchina lo crea l'OS.


Potrebbe forse essere ideato un sistema di anti-tampering? Non lo so per esempio una volta create l'immagine binaria salvarsi l'MD5SUM / hashcode da qualche parte e prima di eseguire il programma verificare che corrisponda?

Tu cosa proponi?


Beh immagino che un problema del genere se lo sarà posto l'architetto dell'OS prima di tirare su le mura no?
Se puoi modificare l'eseguibile, puoi anche modificare il checksum di conseguenza no? ;)
Per un sistema di antitampering gli eseguibili andrebbero firmati. Ma anche in quel caso se sono in possesso di una chiave valida di cifratura (e tutti gli sviluppatori dovrebbero averne una) posso rimpacchettare il tutto e farlo digerire al sistema. Insomma si finisce in un sistema alla Apple dove puoi installare solo da un market place certificato in cui la chiave riconduce ad un ben preciso sviluppatore.


Il GC è scritto in C#, non so molto di quella parte, ma c'è un momento in cui Cosmos parte ed esegue la sequenza di istruzioni in assembler che tutti gli OS hanno sempre eseguito (modalità reale 16 Bit, 64 KB di RAM, ...) poi parte praticamente subito la "macchina virtuale" / "esecutore" C# e quindi il GC inizia a funzionare insieme a tutto il resto del runtime: il codice di Cosmos è normale codice C# dal punto di vista di chi lo scrive gli oggetti sono allocati sull'heap, c'è il garbage collector, ecc...


Per questo mi chiedevo come si fa a deallocare la memoria in C# :D
Il GC dealloca memoria, se è scritto in C# ci deve essere un meccanismo che consente di gestire direttamente la memoria, meccanismo non presente rimanendo in puro C# (e non citiamo il PInvoke che se l'OS è scritto in C# siamo punto e a capo :) )

Mi sapresti indicare dove sta il codice Cosmos relativo al GC?


Sì stackalloc è unsafe, ma a livello 0 (la parte core del Kernel) è ammesso che possa esistere codice unsafe questo è il codice che dovrebbe gestire l'heap io non ci capisco molto, ma come vedi è scritto in C# per quanto appunto unsafe:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Core.Memory/Heap.cs

fano
13-07-2016, 12:16
Allora ieri ho fatto una chiaccherata con Matthijs ter Woord (uno dei lead developer di Cosmos, ci sarebbe anche Chad Z. Hower (Kudzu), ma lo si deve molto raramente in chat!) riguardo X# beh la risposta sul perché il cancelletto davanti alle costanti mi ha lasciato un po' con l'amaro in bocca: "beh perché a noi piace così" :D
(no, nemmeno a me piace!).

Riguardo embeddare X# dentro C# c'è un problema facendo come fa GCC che dal punto di vista di Visual Studio sarebbe una stringa quindi:


Niente più syntax highliting / code completion
Nessun errore da parte del compilatore se scrivi codice errato. Questo è un grosso vantaggio di XS rispetto al sistema precedente (l'errore lo beccava NASM, ma ti mostrava l'assembler non il tuo codice e beh non è immediato associare le 2 cose!)


Io credo che C# potesse embeddare altri linguaggi dentro di sè come fatto con LINQ, ma sembra che fosse l'eccezione non la regola:

https://github.com/dotnet/roslyn/issues/1746

Si potrebbe fare modificando Roslyn, ma è un po' un casino!

Riguardo il discorso come facciamo ad essere sicuri che un programma utente non faccia cose illecite?

Beh intanto per iniziare i programmi utenti sono sempre in formato IL (e Matthijs ter Woord ha tenuto a stressare questo: in Cosmos i programmi sono sempre in formato IL, mai in formato nativo) e quindi prima di essere compilati per essere eseguiti possono e dovranno essere verificati. Il nostro compilatore avrà una black list delle istruzioni che sono "pericolose" e quindi mostrerà una gloriosa eccezzione e l'utente butterà nel cestino l'applicazione :Prrr:

Anche un subset di unsafe sarà accettato perché in realtà un subset di unsafe è safe ed infatti con C# 7 la stessa Microsoft sta esponendo cose parzialmente unsafe senza bisogno di taggare la classe come unsafe come per esempio: Span, Slice, Ref return.
Codice unsafe C# non può comunque fare gli stessi danni che può nelle mani di un hacker esperto fare codice C/C++: quello che è stato fatto per crackare la PS4 e fargli girare sopra Linux (poveretta :cry:) accedendo a strutture del kernel da un programma utente non sarebbe possibile se l'OS di PS4 fosse basato su Cosmos.
(Sì un dispositivo blindato come PS4 è un possibile target di Cosmos: ricordate la licenza MIT? Sony potrebbe riscriverlo completamente e rendere il tutto closed source e il tutto sarebbe perfettamente legale).

Codice automodificante non può esistere usando C#, da vedere se anche Reflection per quanto sia comoda, possa essere accettabile (correggetemi se sbaglio, ma con Reflection io posso chiamare impunemente metodi privati di una classe vero?).

Forse un sistema di signature del binario potrebbe anche non essere necessario, ma ci penseremo nel momento in cui ci occuperemo di come gestire le applicazioni per ora:

"Cart before horses" :D

@tomminno questo è il codice (parziale ci stanno ancora lavorando) di RAT che è in realtà la classe che si occupa di allocare / deallocare memoria, il GC vero e proprio non c'è ancora (sì Cosmos leaka memoria :Prrr:):
https://github.com/CosmosOS/Cosmos/blob/95c0021bf0e03880473098ca46946c64b151501a/source/Cosmos.Core.Memory.Test/RAT.cs

come vedi è codice C# è unsafe perché usa i puntatori anche il GC sarà ovviamente scritto in C# (dovrebbe essere un thread che gira insieme all'applicazione / applicazioni, e userà le funzioni di allocazione / deallocazione di RAT quindi il GC potrebbe essere scritto in safe C# e quindi girerà a un livello più alto visto che non dovrà accedere direttamente a una risorsa privelegiata come la RAM).

cdimauro
14-07-2016, 06:08
Allora ieri ho fatto una chiaccherata con Matthijs ter Woord (uno dei lead developer di Cosmos, ci sarebbe anche Chad Z. Hower (Kudzu), ma lo si deve molto raramente in chat!) riguardo X# beh la risposta sul perché il cancelletto davanti alle costanti mi ha lasciato un po' con l'amaro in bocca: "beh perché a noi piace così" :D
(no, nemmeno a me piace!).
No comment. :doh:
Riguardo embeddare X# dentro C# c'è un problema facendo come fa GCC che dal punto di vista di Visual Studio sarebbe una stringa quindi:


Niente più syntax highliting / code completion
Nessun errore da parte del compilatore se scrivi codice errato. Questo è un grosso vantaggio di XS rispetto al sistema precedente (l'errore lo beccava NASM, ma ti mostrava l'assembler non il tuo codice e beh non è immediato associare le 2 cose!)


Io credo che C# potesse embeddare altri linguaggi dentro di sè come fatto con LINQ, ma sembra che fosse l'eccezione non la regola:

https://github.com/dotnet/roslyn/issues/1746

Si potrebbe fare modificando Roslyn, ma è un po' un casino!
Sarebbe la soluzione migliore, perché trattare il codice X# come stringa è l'ultima cosa che dovreste fare.

Purtroppo C# ha capacità limitate per implementare roba così nuova. Non è un linguaggio che mette a disposizione funzionalità di tipo DSL.

Vi tocca estenderlo, se volete una soluzione elegante e robusta, oppure inventarvi un'altra soluzione: X# è troppo verboso così com'è.
Riguardo il discorso come facciamo ad essere sicuri che un programma utente non faccia cose illecite?

Beh intanto per iniziare i programmi utenti sono sempre in formato IL (e Matthijs ter Woord ha tenuto a stressare questo: in Cosmos i programmi sono sempre in formato IL, mai in formato nativo) e quindi prima di essere compilati per essere eseguiti possono e dovranno essere verificati. Il nostro compilatore avrà una black list delle istruzioni che sono "pericolose" e quindi mostrerà una gloriosa eccezzione e l'utente butterà nel cestino l'applicazione :Prrr:
Sempre che il meccanismo di black list sia ben congegnato e/o non abbia bug. :D
Anche un subset di unsafe sarà accettato perché in realtà un subset di unsafe è safe ed infatti con C# 7 la stessa Microsoft sta esponendo cose parzialmente unsafe senza bisogno di taggare la classe come unsafe come per esempio: Span, Slice, Ref return.
Codice unsafe C# non può comunque fare gli stessi danni che può nelle mani di un hacker esperto fare codice C/C++: quello che è stato fatto per crackare la PS4 e fargli girare sopra Linux (poveretta :cry:) accedendo a strutture del kernel da un programma utente non sarebbe possibile se l'OS di PS4 fosse basato su Cosmos.
(Sì un dispositivo blindato come PS4 è un possibile target di Cosmos: ricordate la licenza MIT? Sony potrebbe riscriverlo completamente e rendere il tutto closed source e il tutto sarebbe perfettamente legale).
Esattamente.
Codice automodificante non può esistere usando C#, da vedere se anche Reflection per quanto sia comoda, possa essere accettabile (correggetemi se sbaglio, ma con Reflection io posso chiamare impunemente metodi privati di una classe vero?).
Dovrebbe essere così, ma non ne sono sicuro.
Forse un sistema di signature del binario potrebbe anche non essere necessario, ma ci penseremo nel momento in cui ci occuperemo di come gestire le applicazioni per ora:

"Cart before horses" :D
Già, ma cominciate a pensare già adesso a un sistema di firma dei binari, perché è necessario.

fano
15-07-2016, 08:45
No comment. :doh:


Sì diciamo che come risposta non l'ho molto capita (sospetto che non abbia capito la domanda, in fondo lui è Olandese, io sono Italiano e ci parliamo in Inglese :D)


Sarebbe la soluzione migliore, perché trattare il codice X# come stringa è l'ultima cosa che dovreste fare.


Beh adesso con XS.Func() non è trattato come stringa, Visual Studio è già in grado di trovare casi di uso errato avviene con i contracts con controlli sintattici veri e propri però è già molto meglio di prima in cui l'errore te lo beccavi da parte di NASM e ti diceva non la riga del tuo codice, ma quella dell'Assembler!


Purtroppo C# ha capacità limitate per implementare roba così nuova. Non è un linguaggio che mette a disposizione funzionalità di tipo DSL.

Vi tocca estenderlo, se volete una soluzione elegante e robusta, oppure inventarvi un'altra soluzione: X# è troppo verboso così com'è.


Sai io ero convinto che appunto essendoci LINQ fosse già possibile invece pare che LINQ sia stata un'eccezione, fa strano vedere che VB.NET, invece, lo sa fare benissimo :cry:
Purtroppo la Microsoft non ne vuole sapere d'implementarlo e Roslyn non sembra molto semplice da modificare...

Non ho capito se quei file .xs in cui il vero X# vivo sono chiamabili da C# altrimenti uno potrebbe scrivere una funzione e poi chiamarla da C#, ma non è veramente codice .NET il '#' è solo pubblicità è più un "macro paster" X# che un vero è proprio linguaggio.


Sempre che il meccanismo di black list sia ben congegnato e/o non abbia bug. :D


Beh uno a non avere bug ci prova, ma non è mica facile :D
La cosa migliore è fare come le grandi corporation avere in casa un hacker e metterlo a stressare l'OS finché non lo buca (e poi risolvere il bug)!


Dovrebbe essere così, ma non ne sono sicuro.


Così almeno mi ha detto Matthijs, ma ha senso per quello per cui è stato pensato C#: questa cosa taglia fuori molti virus / malware....


Già, ma cominciate a pensare già adesso a un sistema di firma dei binari, perché è necessario.

Prima di questo però i binari (nel senso di applicazioni) dobbiamo averli :D

Comunque non è che gli .EXE scaricati dovranno essere firmati (non sarebbe possibile visto che vogliamo essere compatibili il più possibile con normali applicazioni .NET): la firma avverrà all'interno di Cosmos al momento dell'installazione / prima avvio quando l'IL viene compilato e l'immagine nativa generata: è l'immagine nativa che dovrà essere firmata!

fano
25-07-2016, 11:52
Questo Domenica non ho potuto lavorare su Cosmos perché ho deciso finalmente di farmi coraggio e di aggiornare da Windows 8.1 a Windows 10 mica per altro, ma perché è l'ultima settimana che è gratis (e da buon genovese se una cosa è gratis :D).

Vi aggiorno un po' su quello che stanno facendo gli altri:


Si sta tentando di rendere configurabile il layout della tastiera Cosmos attualmente aveva hardcoded il layout US. La prima PR è stata rigettata perchè era stata fatta per mezzo di kludge: https://github.com/CosmosOS/Cosmos/pull/407. La cosa corretta è probabilmente "scardinare" l'hard coding fatto in HAL e spedire verso l'alto i raw scancodes e interpretarli in System secondo il layout selezionato.
Si sta tentando di portare le Winforms di Mono su Cosmos. Io penso sia un po' prematuro...


Se gli impegni lavorativi (ultimamente torno a casa dopo le 21!) non mi stressano troppo voglio studiare in questa settimana un metodo migliore per dichiarare le variabili in X#, attualmente sono aggiunte nel posto sbagliato: dovrebbero essere vicino all'implementazione degli OpCode stessi invece sono all'inizio del kernel.

Comunque qualcuno di voi ha deciso di voler collaborare al progetto? Vi aspettiamo numerosi!

71106
25-07-2016, 13:23
Ma in tutto cio' la domanda e': perche' non l'avete chiamato AlphaWinUX (https://alphawinux.wordpress.com/)? :asd:

fano
25-07-2016, 13:37
Perché questo è un progetto serio ecco perché!

71106
25-07-2016, 14:25
Si, ma se l'aveste chiamato AlphaWinUX avreste avuto un follower in piu'! :D

fano
25-07-2016, 16:17
Beh Cosmos è solo il nome del Kernel se uno volesse fare un OS "satanico" che mixa Windows con Linux e con una punta di Mac OSX e chiamarlo AlphaWinUX potrebbe pure farlo :D
(Magari si riesce ad avere qualcosa che funziona mischiandoli tutti!)

||ElChE||88
25-07-2016, 19:29
Si riferiva al leggendario AlphaWinUX (http://www.hwupgrade.it/forum/showthread.php?t=1707247).

71106
26-07-2016, 17:20
Beh Cosmos è solo il nome del Kernel se uno volesse fare un OS "satanico" che mixa Windows con Linux e con una punta di Mac OSX e chiamarlo AlphaWinUX potrebbe pure farlo :D
(Magari si riesce ad avere qualcosa che funziona mischiandoli tutti!) Non essere eretico, il vero il vero AlphaWinUX non puo' essere basato su Cosmos perche' deve avere il motore kernel (http://www.hwupgrade.it/forum/showthread.php?p=21710616#post21710616)! :O

fano
07-08-2016, 14:36
Ieri mentre browsavo sono incappavo in un'antica (?) diatriba l'istruzione IDIV è lenta tanto che alcuni compilatori cercano di evitarla ad ogni costo! Per esempio quando la divisione è per un multiplo di 2 si preferisce fare uno shift piuttosto che chiamare IDIV, altri arrivano all'estremo di usare il reciproco e fare la moltiplicazione :eek:

Mi chiedo ma con le ultime CPU è ancora così o è solo una leggenda metropolitana?

Ho fatto un po' di prove con VC++ e questa semplice funzione:


static void DivideBy2(int val)
{
int result = val / 2;
}


viene convertita in assembler in una versione con gli shift:


00E616BE mov eax,dword ptr [val]
00E616C1 cdq
00E616C2 sub eax,edx
00E616C4 sar eax,1
00E616C6 mov dword ptr [result],eax


Analogo codice invece scritto in C# usa semplicemente DIV:


057EE8D8 mov eax,dword ptr [ebp-3Ch]
057EE8DB mov ecx,2
057EE8E0 cdq
057EE8E1 idiv eax,ecx
057EE8E3 mov dword ptr [ebp-40h],eax


Ora è possibile che l'assembler che ottengo da C# sia quello che usa il JIT che - per ovvie ragioni - non può fare tutti sta ragionamenti se il dividendo è multiplo di 2 o cosa... e forse questo ragionamento non può farlo nemmeno l'IL perché magari non è sempre detto per tutti i processori che ci sia differenza tra SAR e IDIV? Magari il JIT vede che ho un core I3 dove IDIV funziona correttamente mentre il VC++ ottimizza per il minimo comun denominatore (486? Pentium II?)?

Mi sto anche chiedendo, ma la CPU non potrebbe da sola cambiare IDIV con SAR quando appropriato?

Probabilmente sono cose che un AOT compiler come .NET Native, CoreRT e IL2CPU dovranno fare insieme ad altri "trucchetti" (eliminazioni di costanti, trasformazioni di divisioni con multipli di 2 in Right Shift, di moltiplicazioni in Left Shift, Loop Unrolling, Auto Vettorizzazione, ecc...) se si vuole arrivare vicini al livello di C/C++...

Un'idea che mi è venuta è un IL2IL compiler che trasforme l'IL della Microsoft in una nuova versione "Machine dependent" che IL2CPU a sua volta ri-mastica per trasformarlo in assembler:


Visual Studio genera il classico IL come farebbe per una normale applicazione
IL2IL interviene e applica varie ottimizzazioni in alcuni casi aggiungendo nuovi opcode per esempio per le operazioni con SSE (auto-vettorizzazione). L'IL generato a questo punto è valido solo per x86
IL2CPU trasforma l'IL ottenuto da IL2IL in assembler senza dover essere troppo cambiato (si dovrà aggiungere il trattamento degli opcode aggiunti ovviamente)


Questo è quanto avveniva in Midori e quanto viene fatto in .NET Native (il secondo IL è chiamato appunto MDIL Machine Dependent IL) peccato che non vogliano rendere Open Source quel compilatore :cry:

Comunque tornando al Cosmos di oggi non quelli di anni ed anni nel futuro mi faceva schifo come dovevo dichiarare le costanti per le operazione con i floating point (attualmente deve esser fatto in tutt'altro file rispetto a dove sono usati e finiscono in una sezione chiamata "kernel stack" :mbe:) così mi hanno suggerito che per adesso potremmo anche metterle nello stack così ho provato a cambiare il codice in questo modo:


// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
//XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true);
XS.Set(ESP, 0x80000000);
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);

XS.SSE.XorPS(XMM0, XMM1);
XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);


Ma la VM ci resta secca eseguendo il mio codice, manco posso debuggare perché il debugger stesso si blocca! Non vedo nessun errore fatale che ammazza la CPU, ma essa muore... che accade?

71106
07-08-2016, 20:49
Ritengo che una singola MOV da o verso la memoria sia assai più lenta di una IDIV. :rolleyes:

Che un compilatore trasformi una divisione in uno shift quando il divisore è potenza di due è normale, credo che qualunque architettura riesca a fare uno shift in un solo colpo di clock.

Che motivazioni riportava la roba che hai letto circa questa lentezza?

cdimauro
07-08-2016, 22:09
@fano: passi la moltiplicazione per potenze di due, ma lo shift a destra NON è equivalente alla divisione quando hai a che fare con interi con segno. Quindi... OCCHIO!

Riguardo ai tuoi problemi con quel pezzo di codice, sarebbe più utile un dump del binario generato.

fano
08-08-2016, 08:48
Ritengo che una singola MOV da o verso la memoria sia assai più lenta di una IDIV. :rolleyes:


Quale mov? Questa 'mov eax,dword ptr [val]'? Beh credo che sia impossibile farlo direttamente su 'val' la shift...


Che un compilatore trasformi una divisione in uno shift quando il divisore è potenza di due è normale, credo che qualunque architettura riesca a fare uno shift in un solo colpo di clock.

Che motivazioni riportava la roba che hai letto circa questa lentezza?

Dicevano che l'operazione DIV è in realtà implementata come una serie di sottrazioni quindi effettivamente - anche usando la logica - non può essere più veloce di uno shift binario :(
Possibile però che i processori moderni abbiano ancora questo problema?


@fano: passi la moltiplicazione per potenze di due, ma lo shift a destra NON è equivalente alla divisione quando hai a che fare con interi con segno. Quindi... OCCHIO!


Beh il numero che passavo alla funzione era positivo (il solito 42 :Prrr:) quindi forse "fingeva" che fosse non segnato? Da notare anche l'istruzione 'cdq' che se ho capito bene lo trasformava in un long (forse unsigned long?).

Mah io resto nel dubbio che fare CDQ + SAR invece che semplicemente IDIV (come fa il compilatore C#) faccia poi tutta sta differenza... tu cosa ne dici?


Riguardo ai tuoi problemi con quel pezzo di codice, sarebbe più utile un dump del binario generato.

Attendendo un po' ottenevo il solito "stack corruption", ma io ho davvero difficoltà a capire come operare con lo stack quando faccio qualcosa ad ESP tutto esplode! Perché? In ESP c'era un float ("intero" a 4 byte), l'ho "mosso" dentro XMM0 e quindi io ci scrivo un altro valore che male ci sarebbe?

Comunque ho cambiato il codice facendo una Push dentro ESP non ho capito perché ho dovuto "muovere" lo stack di 4 se no non funzionava, comunque ottengo il valore coretto "-42.0" peccato che l'asserzione fallisce dicendo che "-42.0" != "-42.0".


// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
//XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true);
//XS.Set(ESP, 0x80000000);
XS.Add(ESP, 4);
XS.Push(0x80000000);
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);

XS.SSE.XorPS(XMM0, XMM1);
XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);


La domanda è che differenza c'è tra fare una MOV in ESP e una PUSH in ESP?

71106
08-08-2016, 13:51
Quale mov? Questa 'mov eax,dword ptr [val]'? Beh credo che sia impossibile farlo direttamente su 'val' la shift... Qualunque MOV. La memoria virtuale richiede che un singolo lookup verso la memoria fisica causi in realta' tre lookup, con una frequenza di clock piu' lenta di quella del processore. E' ovvio che non si puo' sostituire l'istruzione MOV con qualcos'altro, altrimenti la stessa Intel l'avrebbe gia' fatto.


Dicevano che l'operazione DIV è in realtà implementata come una serie di sottrazioni quindi effettivamente - anche usando la logica - non può essere più veloce di uno shift binario :( Che io sappia i circuiti divisori si implementano con reti combinatorie, quindi il computo (per quanto possa essere intricato) avviene sempre in un solo colpo di clock. Un colpo di clock richiede esattamente lo stesso tempo, tanto per le divisioni quanto per gli shift. Forse mi sbaglio riguardo ai divisori?

71106
08-08-2016, 13:55
Che io sappia i circuiti divisori si implementano con reti combinatorie, [...] Primo link che ho trovato su Google: http://a2.pluto.it/a2/a2278.htm#almlanchor21100

Gli ho solo dato un'occhiata, ma il tipo mi sembra riuscire nell'implementazione di un divisore senza usare microcodice, solo una rete combinatoria.

ingframin
08-08-2016, 15:23
Primo link che ho trovato su Google: http://a2.pluto.it/a2/a2278.htm#almlanchor21100

Gli ho solo dato un'occhiata, ma il tipo mi sembra riuscire nell'implementazione di un divisore senza usare microcodice, solo una rete combinatoria.

Che io sappia i processori moderni usano o il metodo di Newton-Raphson o il metodo di Goldschmidt che entrambi richiedono più o meno cicli di clock in base alla precisione richiesta.

Il circuito combinatorio di quel documento illustra in linea di principio come si fa la divisione con un circuito combinatorio, ma quella soluzione è troppo lenta per i processori moderni.
Attenzione che a disegnare i blocchettini negli schemi non ci vuole niente, poi però i segnali si devono propagare in un mezzo fisico e li escono le magagne e ciò che funziona su carta funziona sempre meno bene (da cui scaturisce la minchiata che ho scritto nella mai firma, che in realtà tanto minchiata non è...).

[edit]
Wikipedia riporta anche quest'altro metodo:
https://en.wikipedia.org/wiki/Division_algorithm#SRT_division
ma non so se effettivamente è ancora usato da Intel o no.
Le look up table velocizzano molto i calcoli ma quanto spazio occupano sul silicio!

fano
08-08-2016, 15:37
Allego questo PDF come si può vedere per processori vecchi DIV e MUL potevano anche occupare 46 cicli (!) mentre SHL / SHR ne occupano quasi sempre solo 1:

http://www.agner.org/optimize/instruction_tables.pdf

quindi sì sembrerebbe un'ottimizzazione che ha senso fare anche con le CPU di oggi mi chiedo perché C# non lo faccia non sembra troppo complessa da implementare o mi perdo qualcosa?

Comunque tornando al mio problema:


// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
//XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true);
//XS.Set(ESP, 0x80000000);
XS.Add(ESP, 4);
XS.Push(0x80000000);
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
XS.SSE.XorPS(XMM0, XMM1);
XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);


Perché non sta funzionando? Il risultato è -42.0 come atteso, ma l'asserzione fallisce: non capisco!
Quando il valore era una constante scritta nella sezione "DATA" funzionava alla perfezione...

71106
08-08-2016, 15:50
Attenzione che a disegnare i blocchettini negli schemi non ci vuole niente, poi però i segnali si devono propagare in un mezzo fisico e li escono le magagne e ciò che funziona su carta funziona sempre meno bene (da cui scaturisce la minchiata che ho scritto nella mai firma, che in realtà tanto minchiata non è...). Minchia... Se ho capito bene, mi sono perso il periodo storico in cui il clock dei processori mainstream e' divenuto talmente elevato da non consentire la propagazione del segnale alle reti combinatorie troppo lunghe. :D

ingframin
08-08-2016, 15:52
Allego questo PDF come si può vedere per processori vecchi DIV e MUL potevano anche occupare 46 cicli (!) mentre SHL / SHR ne occupano quasi sempre solo 1:

http://www.agner.org/optimize/instruction_tables.pdf



Mi pare normale, si usa un barrel shifter (https://en.wikipedia.org/wiki/Barrel_shifter)!

Sul perché c# non lo faccia non so che rispondere :( Sei sicuro che il codice compilato dal JIT non faccia la sostituzione?

Tieni pure conto che sostituire una divisione intera per due con uno shift a destra ti fa perdere il resto della divisione. Quindi non sono sicuro al 100% che sia una cosa sempre fattibile.

fano
08-08-2016, 16:23
Il C++ faceva questa ottimizzazione, C# apparentemente no! Ma appunto non sono cosa intenda Visual Studio con quel "disassemble"... sinceramente avrebbe più senso se mostrasse l'IL invece che ASM x86!

Beh in quel caso particolare io non necessitavo del resto quindi lo shift era perfettamente lecito come sostituto della divisione :D

71106
08-08-2016, 20:50
che vuol dire che ti fa perdere il resto? e' una divisione intera, non ce l'ha il resto. I processori Intel hanno un bit contenente il resto dell'ultima operazione che ne ha prodotto uno, il bit e' testabile tramite jump condizionati. Le istruzioni (I)DIV popolano quel bit, gli shift chiaramente no.

Va da se' che e' un problema per il compilatore e che il programmatore C# non se ne deve minimamente preoccupare. :p

71106
09-08-2016, 07:27
ah, non lo sapevo. ho sempre lavorato con architetture molto piu' spartane ;) Ho i ricordi offuscati... Ho appena ricontrollato qui (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf), pag. 284 del vol. 2A (Instruction Set Reference). Il bit a cui mi riferivo e' il CF ("Carry Flag", testabile tramite JC e JNC), tuttavia sia DIV che IDIV lo lasciano invariato poiche' giustamente il resto puo' essere arbitrariamente grande. Viceversa, il resto viene memorizzato nel registro general-purpose D (DX, EDX, o RDX, a seconda della modalita' del processore).

fano
09-08-2016, 09:03
Comunque in caso di resto di divisione per 2 credo - di nuovo - ci sia qualche ottimizzazione possibile invece che fare la IDIV (o l'istruzione apposita per ottenere il resto che in x86 ci sarà sicuramente :D) forse un & 2?

In ogni caso assembler mi sta facendo totalmente impazzire!
Ricapitoliamo sto cercando di negare un valore floating point faccio 2 test la negazione di un numero positivo che mi torna lo stesso numero negato (42 ==> -42) e l'inverso (-42 ==> 42).

Questa è la prima versione che funziona perfettamente:


// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true);
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
XS.SSE.XorPS(XMM0, XMM1);
XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);


__floatsignbit è definito in un altro file completamente diverso (CosmosAssembler.cs) nel kernel c'è una sezione DATA dove ci sono tutte le constanti __floatsignbit finisce in fondo insieme alle altri costanti che introdotto per convertire unsigned int in float ecc...

La seconda versione è analoga semplicemente la constante è dichiarata dentro il metodo Execute() (poco prima del codice che vedete) invece che essere in un file a caso: l'unica differenza è che nel kernel __floatsignbit si trova non più in fondo in una posizione random sempre dentro la stessa sezione data.
Ebbene in questo caso come per magia (!) il primo test funziona, ma il secondo no... dicendo - senza alcuna vergogna che -42.0 != -42.0 :cry:

Questa è la III versione in cui la constante è "pushata" nello stack:

// There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
XS.Add(ESP, 4);
XS.Push(0x80000000);
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
XS.SSE.XorPS(XMM0, XMM1);
XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);


ancora una volta il I test funzione, ma il secondo no (-42.0 != -42.0).

Prima che vi emozionate tutti lo so che gli operatori == e != non funziona con i float ed infatti uso questa routinetta fornitami gentilemente dalla Microsoft per testare se sono uguali ha sempre funzionato per tutti i test che ho fatto (e funziona anche per -42.0 quando la constante è dichiarata dentro CosmosAssembler.cs):


/* The single== equality operator is so imprecise to not be really ever useful we should be happy if the two values are "similar" */
private static bool SinglesAreEqual(Single left, Single right)
{
// Define the tolerance for variation in their values
Single difference = (Single) Math.Abs(left * .00001);

if (Math.Abs(left - right) <= difference)
return true;
else
return false;
}


Cosa ne pensate? Avete qualche idea?

fano
24-08-2016, 13:07
Con oggi sono entrato ufficialmente nel gruppo direttivo di Cosmos "CoreDev - The Inner Sanctum":
https://github.com/orgs/CosmosOS/teams/coredev

Beh devo dire che è una bella soddisfazione :D

Ovviamente non è che mi poteva andare bene non riuscivano ad aggiungermi Github diceva che io NON esisto che ho conflitti con sto tizio:
https://github.com/undefined

Poi si scopre qual era il problema? Il mio userId di github è fanoI (con la i), ma loro scrivevano fanol (con la elle!) per forza che non mi arrivava nessuna notifica :Prrr:

Detto questo abbiamo deciso quali sono i piani dopo il merge del mio lavoro sui float (e la chiusura di più PR possibili) e il termine del lavoro sul memory manager (RAT) passeremo da .NET a .NET core questo dovrebbe permetterci di avere molti, molti meno plug da sviluppare così da poterci concentrare sul vero lavoro che è scrivere il kernel in C#!

Si è subito però scatenato un dibattito compiliamo anche IL2CPU con .NET core? Temiamo che ci saranno problemi con reflection e feature avanzate dato che .NET core è ancora immaturo. D'altro canto il grosso vantaggio sarebbe che usando .NET core potremmo molto più facilmente rendere possibile compilare Cosmos su MacOS e su Linux!

Voi cosa ne pensate?

Shirov
27-08-2016, 10:13
Comunque in caso di resto di divisione per 2 credo - di nuovo - ci sia qualche ottimizzazione possibile invece che fare la IDIV (o l'istruzione apposita per ottenere il resto che in x86 ci sarà sicuramente :D) forse un & 2?


Mi inserisco solo perchè recentemente, spulciando nei miei appunti del passato, ho trovato questo:

"divisione per 2 x86:
sar eax, 1"

francamente non ricordo quasi nulla dell'argomento per cui non garantisco che possa in effetti essere utile al discorso.

EDIT: sorry ho letto di fretta a te interessava il discorso del resto. Come non detto.

fano
27-08-2016, 14:17
Il trucco vale per tutti i multipli di 2 quindi: divisione per 4 == shift a destra di 2!

Per il modulo sempre per multipli di 2:
x % 2n == x & (2n - 1)

quindi per esempio: x % 4 == x & 3

https://en.wikipedia.org/wiki/Modulo_operation

Comunque mi sono installato la release 1.0 di .Net Core e la buona notizia è che la / 2 è ora ottimizzata con uno shift come atteso!

S'aggiunga: Ottimizzazione divisione con costanti (https://www.google.it/url?sa=t&rct=j&q=&esrc=s&source=web&cd=10&cad=rja&uact=8&ved=0ahUKEwjFm5La1eHOAhWGVRoKHV_sCX4QFghZMAk&url=http%3A%2F%2Fwww.hackersdelight.org%2FdivcMore.pdf&usg=AFQjCNGgTLjsN2TnjGOdwzsYU0wXFG-ghg&sig2=ddn9PbnLNhVAdTmpDYVIjg&bvm=bv.131286987,d.bGs).
(Che casino :eek:)

Io mi sono predisposto già a compilare Cosmos con .Net Core, ma mi sa che i lavori sul gestore di memoria RAT si protrarranno per le lunghe :cry:

WarDuck
28-08-2016, 21:54
Edit.

fano
23-10-2016, 17:25
Allora vi aggiorno un po':

1. RAT è stato integrato nel main branch e dopo i primi bachetti (fixati) ora Cosmos ha il suo bravo gestore di memoria
2. L'integrazione di Cosmos col Net Core runtime procede su un suo branch separato (https://github.com/CosmosOS/Cosmos/tree/NetCore) il grosso dei problemi che stiamo avendo è dovuto all'immaturità della cosa sembra Visual Studio si incasini tra PCL, Net Core, Net Standard... se non ci capisce lui figurarsi noi :D

E per quanto riguarda me?
Visto che c'è grande richiesta di fare grafica su Cosmos e si stanno già forkando 13 GUI diverse (:cry:) si è deciso che doveva esserci una soluzione pulita e funzionante dentro Cosmos e che me ne sarei occupatp io.

Questa è la nostra idea:
https://github.com/fanoI/Cosmos/wiki/Cosmos-Graphic-Revamp

ma prima di arrivarci abbiamo un altro grosso problema ci sono attualmente 2 driver in Cosmos per pilotare la VGA:

1. VGADriver modalità testuale e modalità grafica fino a 320x200@256 colori
2. VBEDriver modalità grafica fino a 1600x1200@truecolor

Hanno ambedue dei problemini il primo manco tanto un problemino: non funziona proprio! Il secondo non è davvero un driver VBE, ma è l'implementazione di VBE secondo Bochs quindi non è la cosa vera che dovrebbe andare su tutte le schede video dal 2000 in poi...
(a parte il nome VBE funziona però! Ma già non funziona su VmWare l'emulatore più diffuso quindi non serve a nulla quel driver :eek: )

Il driver VGA è questo:
https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.HAL/Drivers/VGAScreen.cs

che sembra grosso modo derivare da questo codice C:
http://files.osdev.org/mirrors/geezer/osd/graphics/modes.c

Il mio kernel di test fa semplicemente questo:


VGA.SetGraphicsMode(ScreenSize.Size320x200, ColorDepth.BitDepth8);
VGA.SetPixel(42, 42, 0x000003); // 3 dovrebbe essere il colore "ciano"


Bochs scrive che il cambio di modo è effettuato, ma lo schermo resta tristemente nero :cry:

Avere due possibili driver (uno solo avrebbe girato a run time) era interessante anche per capire che l'idea di Canvas era veramente fatta bene cioè per esempio ho VmWare e disegno un rettangolo con lo sfigato driver VGA poi uso Bochs e disegno lo stesso rettangolo con il driver VBE che non è VBE e sono a cavallo! Farlo solo con uno rischierei di non avere una cosa universale... quindi magari scriveremo un driver per la GPU di VmWare e scopriamo che Canvas non era veramente venuto.

Avete qualche idea?

cdimauro
24-10-2016, 05:53
Ne abbiamo parlato in privato, ma appena posso mi smazzo il lungo PVT e ti rispondo. :fagiano:

Rispondo soltanto a questo, che avevo perso di vista:
Il trucco vale per tutti i multipli di 2 quindi: divisione per 4 == shift a destra di 2!
Assolutamente sì per i numeri senza segno, e no per quelli con segno.

In generale in quest'ultimo caso vale la seguente:
x / 2^n = (x + (2^n - 1 if x < 0 else 0)) >> n
Per il modulo sempre per multipli di 2:
x % 2n == x & (2n - 1)

quindi per esempio: x % 4 == x & 3

https://en.wikipedia.org/wiki/Modulo_operation
Occhio a come il linguaggio definisce le divisioni quando gli operandi hanno il segno. Il modulo potrebbe essere dotato di segno.

fano
24-10-2016, 10:41
Mah mi chiedo alla fine, ma vale la pena davvero cambiare le divisioni con gli shift e i moduli con gli and se ci sono tutte queste trappole? Perché la CPU non può farsele da sole queste cose (magari quelle può moderne lo fanno pure, ma si ottimizza per il caso più generico... il 486)?

Nei test che feci ho visto che anche Visual Studia fa questi "giochini" oltre che GCC e Clang quindi sicuramente è un ottimizzazione "benefica" però mi fa pensare sembra così semplice la divisione :p

Ritornando alla VGA devo forse settare la palette? Ovvero la palette di default dopo il boot mappa tutti i 256 possibili valori sul nero?

GTKM
24-10-2016, 12:15
Mah mi chiedo alla fine, ma vale la pena davvero cambiare le divisioni con gli shift e i moduli con gli and se ci sono tutte queste trappole? Perché la CPU non può farsele da sole queste cose (magari quelle può moderne lo fanno pure, ma si ottimizza per il caso più generico... il 486)?

Nei test che feci ho visto che anche Visual Studia fa questi "giochini" oltre che GCC e Clang quindi sicuramente è un ottimizzazione "benefica" però mi fa pensare sembra così semplice la divisione :p

Ritornando alla VGA devo forse settare la palette? Ovvero la palette di default dopo il boot mappa tutti i 256 possibili valori sul nero?

Beh, la divisione di per sé tanto semplice non lo è mai stata. Lo shift dei bit ha un costo "computazionale" inferiore, a livello di CPU. A meno che le cose non siano cambiate recentemente. :D
Ovviamente, lo shift vale solo quando il divisore è potenza di due, e per numeri senza segno, come ha detto cdimauro, altrimenti bisogna tener conto di 'ste cose.

cdimauro
24-10-2016, 20:55
Mah mi chiedo alla fine, ma vale la pena davvero cambiare le divisioni con gli shift e i moduli con gli and se ci sono tutte queste trappole? Perché la CPU non può farsele da sole queste cose (magari quelle può moderne lo fanno pure, ma si ottimizza per il caso più generico... il 486)?

Nei test che feci ho visto che anche Visual Studia fa questi "giochini" oltre che GCC e Clang quindi sicuramente è un ottimizzazione "benefica" però mi fa pensare sembra così semplice la divisione :p
Infatti i benefici ci sono sicuramente.
Ritornando alla VGA devo forse settare la palette? Ovvero la palette di default dopo il boot mappa tutti i 256 possibili valori sul nero?
No, già di default il RAMDAC è caricato coi classici 16 colori della CGA, più diverse tonalità fino a coprire tutti e 256 colori.

Dunque il problema sarà un altro. Butta via Bochs. :D

fano
25-10-2016, 08:53
Purtroppo anche con VmWare vedo un "grazioso" schermo nero :cry:

Mi dicono che un tempo la cosa funzionava anche se era molto lento (5 secondi per mostrare un pixel! Probabilmente la nostra gestione dei delegates ha qualcosa che non va) io l'ho lasciato 30 secondi, ma nulla accadeva.

Questa è la SetPixel, mi pare OK:


public void SetPixel320x200x8(uint x, uint y, uint c)
{
mIO.VGAMemoryBlock[(y * 320) + x] = (byte)(c & 0xFF);
}


dove VGAMemoryBlock è:


MemoryBlock08 VGAMemoryBlock = new MemoryBlock08(0xA0000, 1024 * 64);


ovvero 64 KB mappati all'indirizzo della VGA 0xA0000...

A me sembra tutto OK, ho molti più dubbi su come viene programmata la VGA settando quei registri con quei valori "a caso" boh...

cdimauro
25-10-2016, 20:25
Ma per adesso non puoi semplicemente generare delle istruzioni con X#, che settano un po' di pixel sullo schermo 320x200, con tutti e 256 colori? Così vedi se intanto l'accesso al framebuffer funziona.

fano
26-10-2016, 09:35
Nel ring1 (HAL) non si può usare X# solo nel ring 0 infatti tutte le operazioni sulla memoria grezza solo nascoste nel MemoryBlock... le astrazione a volte quando poi si vogliono fare "porcate" sono un po' tra i piedi (beh del resto esistono - le astrazioni - per impedirti di farle... le porcate :D).

Sai cosa penso? Che alla fine ci siano qualche casino in questo calcolo:

[(42 * 320) + 42] (che dovrebbe fare 13482) sono "unsigned int" x ed y e magari fa qualche strano casino anche perché l'indice poi è int quindi c'è anche una conversione implicita tra uint e int...

anche questo calcolo semplice potrebbe fregarmi:

(byte)(c & 0xFF) ('c' è di nuovo un uint e magari l'end con uint non funziona o il cast a byte).

Quindi il mio piano è di dividere l'operazione in calcolo di "where" e di "color" e stamparli, vediamo che valori escono...

I tipi unsigned alla fine più uso C# e penso che a parte byte non hanno davvero senso infatti non tutti i linguaggi .NET li implementano e NON dovresti usarli in classi pubbliche.
Java se avesse definito byte come unsigned (C# l'ha fatto infatti) avrebbe avuto molte meno critiche sulla mancanza dei tipi unsigned la loro intuizione era corretta...

Infatti la futura classe Canvas userà int tornando eccezione se si passano valori fuori range al costruttore come giusto che sia :D

cdimauro
26-10-2016, 20:55
Non credo che ci siano problemi relativi a quei calcoli.

Ma una cosuccia non potresti farla? Alla partenza di Cosmos, in ring 0, scrivi una manciata di istruzioni X# per pulire lo schermo e scrivere qualche pixel. Giusto per vedere se qualcosa funziona.

fano
27-10-2016, 11:44
Non credo che ci siano problemi relativi a quei calcoli.


Mah ricordiamoci che il compilatore lo scriviamo noi, magari c'è qualche casino nell opcode add se il tipo è unsigned o (più probabile) nel cast da uint a int...

Mi sa che prima di RAT era lento, ma funzionava :cry:


Ma una cosuccia non potresti farla? Alla partenza di Cosmos, in ring 0, scrivi una manciata di istruzioni X# per pulire lo schermo e scrivere qualche pixel. Giusto per vedere se qualcosa funziona.

Forse non è chiaro, ma il driver non chiama il BIOS, ma gira in modalità protetta quindi temo non siano una manciata d'istruzioni almeno vedendo il codice C (e il C# da esso derivato) per settare il modo e poi disegnare sullo schermo...

cdimauro
27-10-2016, 18:15
Mah ricordiamoci che il compilatore lo scriviamo noi, magari c'è qualche casino nell opcode add se il tipo è unsigned o (più probabile) nel cast da uint a int...

Mi sa che prima di RAT era lento, ma funzionava :cry:
Allora taglia la testa al toro: niente calcoli. Passagli direttamente l'offset a cui scrivere.
Forse non è chiaro, ma il driver non chiama il BIOS, ma gira in modalità protetta quindi temo non siano una manciata d'istruzioni almeno vedendo il codice C (e il C# da esso derivato) per settare il modo e poi disegnare sullo schermo...
Per settare il modo sì, ma per scrivere qualche pixel sarà giusto una manciata di istruzioni.

syngian
03-11-2016, 09:14
Questo è un buon sito (un po' vecchiotto, ma d'altra parte non c'è nulla di nuovo sotto il sole della VGA) riguardo la programmazione della VGA.
http://www.brackeen.com/home/vga

Se ti accontenti di una risoluzione grafica 320x200 a 256 colori basta switchare in VGA mode 0x13 (è una delle risoluzioni standard che hanno tutte le schede video)... senza problemi puoi arrivare ad una risoluzione di 640x480, anche se occorre qualche attenzione con i registri VGA e qualche linea di codice in più, ma per i tuoi esperimenti mi pare che il VGA mode 0x13 è sufficiente.

Questa estate non sapevo come fare e mi sono deciso di buttare giù un sistema operativo derivato dall'Amiga OS... il sistema si chiama XAM OS (eXtended AMiga OS) e nel mese di agosto ho fatto un bootloader a 2 stadi e una debug console (che in effetti è un mini sistema operativo a se stante) in 20 k di codice.

Non so quanto sia sofisticato il vostro X#, ma per settare i registri VGA basta semplicemente scrivere e/o leggere con le istruzioni assembler outb, outw, inb, inw direttamente
oppure incapsulate in una funzione (ti metto sotto un esempio in C e assembler in linea del CCG di uno dei moduli del mio XAM).

/** XAM ************************************************************************
**
** $VER: main.c 0.0 (01.08.2016)
**
** DESC: Kernel debug console: C code entry
**
** Note:
** code derived from bkerndev - Bran's Kernel Development
** by Brandon F. (friesenb@gmail.com)
*******************************************************************************/

#include "system.h"

void *memcpy(void *dest, const void *src, SIZE count)
{
const UBYTE *sp = (const UBYTE *)src;
UBYTE *dp = (UBYTE *)dest;
for (; count != 0; count--) *dp++ = *sp++;
return dest;
}

void *memset(void *dest, LONG val, SIZE count)
{
CHAR a = val;
UBYTE *dp = (UBYTE *)dest;
for (; count != 0; count--) *dp++ = a;
return dest;
}

UWORD *memsetw(UWORD *dest, UWORD val, SIZE count)
{
UWORD *dp = (UWORD *)dest;
for (; count != 0; count--) *dp++ = val;
return dest;
}

SIZE strlen(const CHAR *str)
{
SIZE retval;
for (retval = 0; *str != '\0'; str++) retval++;
return retval;
}

UBYTE inportb(UWORD port)
{
UBYTE rv;
ASM volatile ("inb %1, %0" : "=a" (rv) : "dN" (port));
return rv;
}

UWORD inportw(UWORD port)
{
UWORD rv;
ASM volatile ("inw %1, %0" : "=a" (rv) : "dN" (port));
return rv;
}

void outportb(UWORD port, UBYTE data)
{
ASM volatile ("outb %1, %0" : : "dN" (port), "a" (data));
}

// This function outputs a word to a hardware port, added for enable/disable the video hardware text cursor.

void outportw(UWORD port, UWORD data)
{
ASM volatile ("outw %1, %0" : : "dN" (port), "a" (data));
}

extern UBYTE heap_base;
static UBYTE *heap_break = &heap_base;

// a simple initial memory management
// heap_base is setted in the linker script and point at the end of bbs section (is the start of free memory after the loaded kernel)

// srbk() (or mmap) is the function called by standard C library function Malloc() & friends for obtain chunk of memory from the system
// for their internal managed pool for the allocation dynamic memory. Malloc() when the internal heap run out of memory call sbrk() for obtain
// more memory from the system), the drawback is that the memory managed by Malloc() & friends is never returned to the system.
// now the rudimentale memory management is working, be carefull, the stuff of the heap_base is a finesse, is possible brutally set for example
// heap_base at 4MB memory address (heap_break=0x400000) and the stack pointer where u like.

static void *sbrk(SIZE size)
{
//#define MEM_BLOCKSIZE (sizeof(APTR)*2) // 2 times of sizeof APTR -- 8/16 bytes for 32/64 bit system
//#define MEM_BLOCKMASK (MEM_BLOCKSIZE-1)
//if (num & MEM_BLOCKMASK) num = (num + MEM_BLOCKSIZE) & ~MEM_BLOCKMASK;

SIZE num = heap_break;

//-- align to 4 --
if (num & 3) {
num = (num + 4) & ~3;
heap_break = (void *)num;
}

void *temp = heap_break;
heap_break += size;
return temp;
}

int kernel_main()
{
// gdt_install(); dont need, the initial kernel gdt is already setting in kernel.asm with a simple preprocessor stuff
init_video(); // really dont need (now the screen routines work without initialization, but is ok )

CursorEnabled(FALSE); //disable the hardware blinking cursor

UBYTE msg1[] = "- XAM OS (eXtended AMiga OS) -\n";
UBYTE msg2[] = "KICKSTART 32 bit running in protect mode at 0x100000 address\n";

GotoXY((80 - strlen(msg1)) / 2, 2); puts(msg1);
GotoXY((80 - strlen(msg2)) / 2, 4); puts(msg2);

idt_install();
isrs_install();
irq_install();
timer_install();
keyboard_install();

ASM volatile ("sti"); // enable interrups

/*
int x, y;
x = GetCursorX;
y = GetCursorY;
SetTextColor(1, 15);
GotoXY(1, 1); puts("interrups enabled");
SetTextColor(15, 3);
GotoXY(x, y);
*/

puts("interrups enabled - write something - Press F1 for enable/disable the hardware cursor\n");
CursorEnabled(TRUE);

// dont touch this infinite loop
for (;;);
}


e poi usi le funzioni per scrivere e leggere nei registri VGA.

/** XAM ************************************************************************
**
** $VER: scrn.c 0.0 (01.08.2016)
**
** DESC: Kernel debug console: screen output I/O functions
**
** Note:
** code derived from bkerndev - Bran's Kernel Development
** by Brandon F. (friesenb@gmail.com)
*******************************************************************************/

#include "system.h"

/* These define our textpointer, our background and foreground
* colors (attributes), and x and y cursor coordinates */
UWORD *textmemptr = (UWORD *)0xB8000;
UWORD attrib = 63; // SetTextColor(15, 3);

UWORD csr_x = 0, csr_y = 0;
BOOL CursorVisible = TRUE;

/* Scrolls the screen */
void scroll(void)
{
UWORD blank, temp;

/* A blank is defined as a space... we need to give it backcolor too */
blank = ' ' | (attrib << 8);

/* Row 25 is the end, this means we need to scroll up */
if (csr_y >= 25)
{
/* Move the current text chunk that makes up the screen back in the buffer by a line */
temp = csr_y - 25 + 1;
memcpy(textmemptr, textmemptr + temp * 80, (25 - temp) * 80 * 2);

/* Finally, we set the chunk of memory that occupies the last line of text to our 'blank' character */
memsetw(textmemptr + (25 - temp) * 80, blank, 80);
csr_y = 25 - 1;
}
}

/* Updates the hardware cursor: the little blinking line
* on the screen under the last character pressed! */
void move_csr(void)
{
UWORD temp;

if (CursorVisible == FALSE) return;

/* The equation for finding the index in a linear
* chunk of memory can be represented by:
* Index = [(y * width) + x] */
temp = csr_y * 80 + csr_x;

/* This sends a command to indicies 14 and 15 in the
* CRT Control Register of the VGA controller. These
* are the high and low bytes of the index that show
* where the hardware cursor is to be 'blinking'. To
* learn more, you should look up some VGA specific
* programming documents. A great start to graphics:
* http://www.brackeen.com/home/vga */


outportb(0x3D4, 14);
outportb(0x3D5, temp >> 8);
outportb(0x3D4, 15);
outportb(0x3D5, temp);
}

// set x,y cursor coordinates x=1-80, y=1-25, 0 for skip x or y setting, example: gotoxy(0,5) set only y
void GotoXY(WORD x, WORD y)
{
if (x >= 1 && x <= 80) csr_x = x-1;
if (y >= 1 && y <= 25) csr_y = y-1;
}

WORD GetCursorX(void)
{
return csr_x + 1;
}

WORD GetCursorY(void)
{
return csr_y + 1;
}

/* Clears the screen */
void cls()
{
UWORD *ptr = textmemptr;
UWORD blank;
UWORD i;

/* The 'short' that will be used to represent a space with color */
blank = ' ' | (attrib << 8);

/* Sets the entire screen to spaces in our current color, 80*25 = 2000 */
for (i = 0; i < 2000; i++)
*ptr++ = blank;

/* Update the virtual cursor, and then move the hardware cursor */
csr_x = 0;
csr_y = 0;
move_csr();
}

/* Puts a single character on the screen */
void putch(const char c)
{
UWORD *ptr;

/* Handle a backspace, by moving the cursor back one space */
if (c == 0x08)
{
if (csr_x != 0) csr_x--;
}
/* Handles a tab by incrementing the cursor's x, but only
* to a point that will make it divisible by 8 */
else if (c == 0x09)
{
csr_x = (csr_x + 8) & ~(8 - 1);
}
/* Handles a 'Carriage Return', which simply brings the
* cursor back to the margin */
else if (c == '\r')
{
csr_x = 0;
}
/* We handle our newlines the way DOS and the BIOS do: we
* treat it as if a 'CR' was also there, so we bring the
* cursor to the margin and we increment the 'y' value */
else if (c == '\n')
{
csr_x = 0;
csr_y++;
}
/* Any character greater than and including a space, is a
* printable character. The equation for finding the index
* in a linear chunk of memory can be represented by:
* Index = [(y * width) + x] */
else if (c >= ' ')
{
ptr = textmemptr + (csr_y * 80 + csr_x);
*ptr = c | attrib << 8; /* character AND attributes color */
csr_x++;
}

/* If the cursor has reached the edge of the screen's width, we
* insert a new line in there */
if (csr_x >= 80)
{
csr_x = 0;
csr_y++;
}

/* Scroll the screen if needed, and finally move the cursor */
scroll();
move_csr();
}

/* Uses the above routine to output a string... */
LONG puts(const char *str)
{
SIZE n;

for (n = 0; n < strlen(str); n++)
{
putch(str[n]);
}
return n;
}

/* Sets the forecolor and backcolor that we will use */
void SetTextColor(unsigned char forecolor, unsigned char backcolor)
{
/* Top 4 bytes are the background, bottom 4 bytes
* are the foreground color */
attrib = (backcolor << 4) | (forecolor & 0x0F);
}

/* Sets our text-mode VGA pointer, then clears the screen for us */
void init_video()
{
//textmemptr = (UWORD *)0xB8000;
cls();
}

/* enable/disable the video hardware cursor in text mode
with status = true the cursor is visible, with false no*/
void CursorEnabled(BOOL status)
{
CursorVisible = status;

if (status)
{
outportw(0x3D4, 0xE0A);
outportw(0x3D4, 0xF0B);
move_csr();
}
else
{
outportw(0x3D4, 0x200A);
outportw(0x3D4, 0xB);
}

}


I nomi dei tipi di dati credo che si capiscono facilmente (io mi attengo strettamente alle convenzioni dell'Amiga OS e uso lo stesso tipo di denominazione adeguata ai tempi) comunque ti metto anche il file che li definisce per sicurezza.. uso un IDE misto CCG/VC++ per lo sviluppo di XAM.. sinceramente non sopporto un abominio come Linux e soprattutto CCG e uso se posso VC++

#ifndef EXEC_TYPES_H
#define EXEC_TYPES_H

/** XAM ***********************************************************************
**
** $VER: types.h 0.1 (01.08.2016) (20.08.2016)
**
** DESC: Data typing - Must be included before any other include
**
** NOTE: standard exec/types.h - modified for kernel debug console
*******************************************************************************/

#define LIBRARY_VERSION 0 // Lowest version supported
#define INCLUDE_VERSION 0 // Version of the include files in use. (Do not use this label for OpenLibrary() calls)

#define _ARCH_x86_32_

#define INLINE __inline
#define VOLATILE volatile

#ifdef _MSC_VER
#define ASM _asm
#else
#define ASM asm
#endif // _MSC_VER

#define EXTERN extern // reference to an external
#define STATIC static // a local static variable
#define REGISTER register // a register variable

#ifndef VOID
#define VOID void
#endif

#ifndef CONST
#define CONST const
#endif

typedef void* APTR; // 32/64 bit untyped pointer (absolute/address pointer)

#undef BYTE

#ifdef __cplusplus
typedef char CHAR; // character
#else
typedef char CHAR; // character
#endif

// the use of CPTR and SPTR is for pointers math and protection, use the CHAR * and CHAR [] as default types
typedef CHAR* CPTR; // character pointer
typedef CHAR* SPTR; // string pointer (NULL terminated)

typedef signed char BYTE; // signed 8-bit quantity
typedef unsigned char UBYTE; // unsigned 8-bit quantity
typedef unsigned char BYTEBITS; // 8 bits manipulated individually

typedef short WORD; // signed 16-bit quantity
typedef unsigned short UWORD; // unsigned 16-bit quantity
typedef unsigned short WORDBITS; // 16 bits manipulated individually

typedef long LONG; // signed 32-bit quantity
typedef unsigned long ULONG; // unsigned 32-bit quantity
typedef unsigned long LONGBITS; // 32 bits manipulated individually

typedef long long QUAD;
typedef unsigned long long UQUAD;
typedef unsigned long long QUADBITS;

#ifdef size_t
typedef size_t SIZE
#endif

#ifndef SIZE
#ifdef _ARCH_x86_32_
typedef ULONG SIZE; // unsigned 32/64-bit quantity
#else
typedef UQUAD SIZE; // unsigned 32/64-bit quantity
#endif
#endif

//---- Types with specific semantics ----

typedef int INT; // integer
typedef float FLOAT32;
typedef double FLOAT64;
typedef UBYTE BOOL; // unsigned, 0 = false, 1 = true

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define BYTEMASK 0xFF

//---- standard NULL declaration ----

#ifdef NULL
#undef NULL
#endif

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif

/*
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __cplusplus
}
#endif
*/

#endif // EXEC_TYPES_H


Questo è il file BUILD.bat che sotto Windows compila il mini sistema operativo Kernel console e crea un image disk (Disk.img) per Bochs.
(servono le versioni a 32 bit di Nasm e MINGW o TDM-GCC).


@IF EXIST TMP @rd /S /Q TMP

@md TMP
@md TMP\BFI

@rem -------------------------
@rem -- Boot -----------------
@rem -------------------------

@cd 0001_00_stage1
nasm -f bin -o ..\TMP\boot.bin Stage1.asm

@cd ..\0001_00_stage2
nasm -f bin -o ..\TMP\BFI\BOOTLDR.SYS Stage2.asm

@cd ..\0002_00_kernel_asm
nasm -f elf -o ..\TMP\kernel.o kernel.asm

@rem -------------------------
@rem -- Kernel ---------------
@rem -------------------------

@cd ..\0002_01_kernel
@rem extra compiler flags: -Wextra -Wall -I./include -ffreestanding
@set "$cc=gcc -std=gnu99 -nostdlib -c -O2 -m32 -march=i686 -lgcc"

%$cc% -o ..\TMP\main.o main.c
%$cc% -o ..\TMP\scrn.o scrn.c
%$cc% -o ..\TMP\idt.o idt.c
%$cc% -o ..\TMP\isrs.o isrs.c
%$cc% -o ..\TMP\irq.o irq.c
%$cc% -o ..\TMP\timer.o timer.c
%$cc% -o ..\TMP\kbd.o kbd.c

@rem -------------------------
@rem -- Linker ---------------
@rem -------------------------

@cd ..\TMP
@set "$ld=ld -T ..\0000_01_Linker\boot.ld -nostdlib --nmagic -o KERNEL.OBJ"

%$ld% kernel.o main.o scrn.o idt.o isrs.o irq.o timer.o kbd.o

objcopy -O binary KERNEL.OBJ BFI\KERNEL.SYS

@cd ..
bfi -f="Disk.img" -b=TMP\boot.bin TMP\BFI

fano
06-11-2016, 14:33
syngian se ho capito bene tu hai usato il BIOS per invocare il modo 0x13, noi questo non possiamo farlo: Cosmos gira in modalità protetta a 32 Bit sempre.

Infatti quello che stiamo usando è un vero e proprio driver VGA programmando il modo scrivendo direttamente sui registri della scheda.
Questa è com'è fatto il nostro driver VGA è puro C# di fatto:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.HAL/Drivers/VGAScreen.cs

l'equivalente di inb, outb sono fatte scrivendo dentro "mIO" che astrae i blocchi di memoria corrispondenti agli indirizzi che in x86 piacciano tanto (in questo caso quindi si legge / scrive su 0xA000...).

cdimauro
06-11-2016, 18:08
In tutta onestà non mi piace il codice attuale, che mi sa tanto di "God class", visto che contiene tutto, e metodi ripetuti per ogni modo grafico supportato.

Una ristrutturazione col concetto di classe schermo e relativi parametri sarebbe necessaria, dividendo gli schermi per lo meno in testuali, bitmapped, e packed/chunky, e delegando ad apposite tabelle l'elenco dei valori da scrivere nei registri della VGA.

Comunque per adesso non avete altra scelta: non potete usare l'int 10 per impostare il modo video.

fano
07-11-2016, 14:08
Sì quel codice non piace molto nemmeno a me onestamente... è chiaramente un porting fatto dal codice C che avevo allegato.

C'è da dire - a nostra parziale discolpa - che mancano ancora molte classi della BCL nel .NET di Cosmos per esempio una mancanza importante è la classe Dictionary che semplificherebbe molto le cose...

Anche l'uso dei delegates sembra essere un problema probabilmente perché l'implementazione in Cosmos non è ancora ben ottimizzata (leggende parlano di 5 secondi per disegnare un pixel! Io ne aspetterei pure 30 per vederlo un pixel :D) quindi sarà una delle cose da cambiare... al momento mi viene in mente solo if / else if / else if :cry:
Quindi molte volte il codice dentro Cosmos non è molto ad "oggetti" anche per questo, speriamo che con .Net Core riusciremo a liberarci dell'incubo dei plug!

Comunque ho intenzione di cambiare un bel po' di cose unificare VGA / VBE facendoli ereditare da una stessa classe astratta ecc...
La parte testuale c'è l'idea effettivamente di fare un driver separato quindi vedendo "virtualmente" la scheda video come 2 dispositivi un dispositivo stupido per scrivere testo (scrivendo probabilmente brutalmente sulla porta 0xB000... come facciamo ora) e un dispositivo più "furbo" per fare grafica che probabilmente avrà driver diversi a seconda dell'hardware.

Non sono comunque sicuro che sbattersi a fare un driver VGA in modalità protetta sia veramente la via giusta da seguire o se sarebbe meglio fare direttamente un vero driver VBE3 usando o sta modalità protetta (se funziona, pare solo Haiku OS sia riuscito ad usarla, forse...) o se è impossibile VM86 che però poi non funziona a 64 bit... quindi boh?

cdimauro
07-11-2016, 19:02
@fano. Ne abbiamo già parlato in privato: la soluzione per lavorare con la VGA è un emulatore 8086, sviluppato tenendo conto delle esigenze di cui hai parlato. Al momento, però, devi riuscire a disegnare un pixel col codice che avete a disposizione. Per le finezze se ne parlerà più avanti. ;)

Riguardo al codice, ho solo esposto le mie idee: non volevo essere brusco o sgarbato. Non è un critica distruttiva, ma serve a spronare a rifattorizzare il codice per renderlo più manutenibile e/o estensibile, specialmente considerato che il progetto è pubblico e sarà sotto gli occhi di tutti. Deformazione professionale, dopo anni di code review... :stordita:

fano
08-11-2016, 08:44
@fano. Ne abbiamo già parlato in privato: la soluzione per lavorare con la VGA è un emulatore 8086, sviluppato tenendo conto delle esigenze di cui hai parlato. Al momento, però, devi riuscire a disegnare un pixel col codice che avete a disposizione. Per le finezze se ne parlerà più avanti. ;)


Sì concordo la cosa che mi annoia di più è che un tempo andava cosa gli hanno fatto a sta povera VGA?

E guarda cosa succede con VirtualBox:

https://github.com/CosmosOS/Cosmos/issues/505

https://cloud.githubusercontent.com/assets/10396295/20081420/6ff09b7c-a504-11e6-9f23-b689f54a8561.png

Io sarei quasi contento almeno è un segno di vita, no?
(Beh qualcosa di diverso c'è Clear() probabilmente fa qualcosa di errato però sullo schermo almeno con VirtualBox viene disegnato qualcosa boh... Bochs e VmWare sono concordi nello schermo nero... e avevo capito che VirtualBox usava la stessa VGA emulata di Bochs ).


Riguardo al codice, ho solo esposto le mie idee: non volevo essere brusco o sgarbato. Non è un critica distruttiva, ma serve a spronare a rifattorizzare il codice per renderlo più manutenibile e/o estensibile, specialmente considerato che il progetto è pubblico e sarà sotto gli occhi di tutti. Deformazione professionale, dopo anni di code review... :stordita:

No avevo inteso benissimo non ti preoccupare e concordo al 100% non voglio che il kernel di Cosmos si riduca come il kernel di Linux che nemmeno sua papà Linus Torvalds riesce più a metterci le mani :D
(vedi il caso del bug novenne che tentò di aggiustare ed il kernel gli esplose in faccia :D)

Virtualbox usa la stessa GPU dell'host (credo sia la configurazione di default) hmm interessante questa differenza tra un GPU reale e una "simulata"...

cdimauro
08-11-2016, 21:17
VirtualBox crea un sacco di problemi. Non ha una compatibilità così elevata. Rimani con VMWare. Oppure puoi provare con QEMU.

E invece di Bochs potresti provare anche DOSBox, che dovrebbe consentire un'emulazione più accurata di un PC, se non ricordo male.

fano
09-11-2016, 10:00
All'inizio pensavo male di Bochs, ma mentre non credo abbia senso usarlo a livello "utente" (troppo incasinato rispetto a VmWare con i soliti file da editare a mano! Classico stile Linux...) devo dire che lato sviluppatore OS non è male per capire che casini stai combinando... c'è dentro persino una specie di GDB!

VmWare essendo appunto più "consumer" si limita a crashare in molti casi...

cdimauro
09-11-2016, 20:06
QEMU ti dà anche la possibilità di lanciare direttamente un kernel, senza passare da un bootloader. ;)

fano
24-11-2016, 08:40
Cosmos su Channel 9 (il canale ufficiale di .NET) Kudzu intervistato da Bertrand Le Roy (Microsoft Program Manager):

https://channel9.msdn.com/Shows/On-NET/Chad-Z-Hower-aka-Kudzu-Cosmos

Se potete loggarvi e votare il video ci fate contenti!

... ci fate ancora più contenti se vi unite al gruppo degli sviluppatori :D

fano
25-11-2016, 18:22
Ebbene i vostri commenti?

cdimauro
28-12-2016, 18:41
Sulla carta sembra molto fico, ma finché sul lato prestazionale non si passerà ai risultati concreti, dubito che si potrà prendere sul serio ciò che dice il main developer.

Non prenderlo come una critica distruttiva, ma sparare che si possa andare 20 volte più velocemente di C++ (se non ricordo male la frase) e poi affermare che attualmente Cosmos è troppo lento perché ancora in fase di debug, non fa certo una buona impressione.

Per cui consiglierei di lasciar perdere certi slogan. Almeno finché non ci sarà qualche risultato a supporto.

Altra cosa, francamente togliete di mezzo completamente X#. E' eccessivamente complesso e farraginoso rispetto a usare direttamente il ben più conosciuto, classico, semplice linguaggio assembly (con sintassi Intel e NON AT&T!).

D'altra parte lo dice anche lo sviluppatore che si usa per pochissime righe di codice. Inutile reinventarsi la ruota con uno strumento così astruso, per così poco: usate l'assembly e metteteci una pietra sopra.

Per il resto promette molto bene. Ma, come ti dicevo anche tempo, se non rilasciate velocemente qualcosa di funzionante, non verrà mai preso seriamente in considerazione. E visto che siete pochi e cercate sviluppatori, sarebbe sicuramente di stimolo vederlo già all'opera.

GTKM
29-12-2016, 07:21
Sulla carta sembra molto fico, ma finché sul lato prestazionale non si passerà ai risultati concreti, dubito che si potrà prendere sul serio ciò che dice il main developer.

Non prenderlo come una critica distruttiva, ma sparare che si possa andare 20 volte più velocemente di C++ (se non ricordo male la frase) e poi affermare che attualmente Cosmos è troppo lento perché ancora in fase di debug, non fa certo una buona impressione.

Per cui consiglierei di lasciar perdere certi slogan. Almeno finché non ci sarà qualche risultato a supporto.

Altra cosa, francamente togliete di mezzo completamente X#. E' eccessivamente complesso e farraginoso rispetto a usare direttamente il ben più conosciuto, classico, semplice linguaggio assembly (con sintassi Intel e NON AT&T!).

D'altra parte lo dice anche lo sviluppatore che si usa per pochissime righe di codice. Inutile reinventarsi la ruota con uno strumento così astruso, per così poco: usate l'assembly e metteteci una pietra sopra.

Per il resto promette molto bene. Ma, come ti dicevo anche tempo, se non rilasciate velocemente qualcosa di funzionante, non verrà mai preso seriamente in considerazione. E visto che siete pochi e cercate sviluppatori, sarebbe sicuramente di stimolo vederlo già all'opera.

Più che altro, X# sembra un po' troppo prolisso.

Ma siamo sicuri che sia davvero conveniente rispetto all'assembly? In fondo, nel computo totale del progetto, la parte interessata è davvero piccola.

cdimauro
29-12-2016, 07:36
Appunto per questo è meglio evitare di reinventarsi la ruota, e sfruttare pari pari il caro, vecchio, semplice assembly. :)

fano
01-03-2017, 17:32
Un po' di aggiornamenti su Cosmos...

Cosmos Graphic Subsystem

Visto che come si dice un'immagine parla più di 1'000 parole:

https://s29.postimg.org/ea1so24bb/Cosmoos_Graphic_Subsystem.jpg

C'è pure un pixel accesso in alto, ma mi sa che la compressione jpg se lo ho è "pappato".

Questo è stato il mio "lavoro" durante le vacanza di Natale, per ora funziona solo con Bochs / VBE perché il driver VGA e quello di VmWare attualmente non sono funzionanti (il secondo forse funziona pure bisognerebbe provarlo), 32 bit / 16'000'000 di colori e risoluzione fino a 1920 * 1200 :eek:

Peccato che per iniziare a disegnare qualche cosa passavano ben 33 secondi, OK che usiamo C#, OK che il compilatore non è ottimizzato, però era davvero strano perché passati i 33 secondi in cui lo schermo era ripulito (lo sfondo blu che vedete), il pixel, le righe ed i rettangoli apparivano tutti contemporaneamente in un tempo non umanamente misurabile (no, non è come dicevano gli utenti che si vedevano i pixel disegnarsi uno per uno!).

Dopo molte false partenze il problema era questo, la classe IOMemoryBlock deve essere inizializzata con quanta memoria video si vuole utilizzare che per ora è dato dalla semplice formula:
H * V * (colorDepth) / 8

essendo però questo nel ring core dove non so più quale risoluzione è utilizzata sono costretto al momento ad inizializzarlo a 1920*1200*4 ( 9'216'000 Byte circa 9 MB) e il metodo Fill() era la cosa più semplice che si possa immaginare:


[DebugStub(Off = true)]
public unsafe void Fill(UInt32 aStart, UInt32 aCount, UInt32 aData)
{
//TODO: before next step can at least check bounds here and do the addition just once to
//start the loop.
//TODO - When asm can check count against size just one time and use a native fill asm op
UInt32* xDest = (UInt32*)(this.Base + aStart);
for (UInt32 i = 0; i < aCount; i++)
{
*xDest = aData;
xDest++;
}
}


Avete intuito il problema? Sono circa 2'000'000 di iterazioni (visto che copiamo a blocchi di interi) e inoltre quando si richiedeva una risoluzione più bassa tipo 1280*1024 Bochs puliva lo schermo e apparentemente finiva, ma poi passavano decine e decine di secondi perché stava riempendo memoria che non era visibile con il colore blu!

Ho provato a combattere contro la realtà dei fatti (Fill() va scritta in assembler) e ho provato orridi truschi con array con blocchi da 1024 ricopiati con Array.BlockCopy(), ma:

1. ArrayBlockCopy() ti filla l'Array tutto con 0 (ovvero è bacata!)
2. C# non è C (!) e pensa che non sia "bello" assegnare un puntatore ad un array ("The Pit of Success") e mi ha impedito di farlo con tutte le sue forze

Così mi sono rassegnato a fare la cosa in Assembler, ma in realtà l'approccio che ho usato è ibrido fino ad un certo threshold può essere fatto in C# (unsafe ovviamente) e solo una piccola parte avviene in ASM / X#.

1. Se il buffer è minore di 15, la Fill() avviene con tipi primitivi (per esempio se il buffer è di 4 byte viene "rivalutato" come un int e si fa una semplice assegnazione, se è 7 byte si assegna un int, uno short e un byte)
2. Con il metodo Math.ModDivRem() si divide per 16 e si ottiene anche il resto
3. Per "definizione" il resto è minore di 16 quindi si fa un bel for() in C# valutando il buffer come array di byte
4. A questo punto per fare una copia a blocchi di 16 si usa assembler scrivendo il valore dentro ad un registro XMM

Questo è più o meno quello che fa la memset() implementata dentro GCC [1]

Purtroppo ho perduto un po' di tempo perché volevo far prima facendo le cose su Windows e poi solo quando avevo una Fill() funzionante portarla su Cosmos (anche se è più veloce che far partire Windows o Linux caricare un intero Sistema Operativo solo per chiamare una funzione è un po' una menata :D), visto che Cosmos è a 32 bit e che credevo usasse la CDECL ho pensato astuto come un procione di mettere CDECL negli attributi della P/Invoke della mia DLL scritta in assembler con NASM... e SEGFAULT :cry:

Pare che Visual Studio quando il SO è a 64 Bit (come nel mio caso) ignori completamente l'attributo CDECL anche se tu richiedi specificatamente di compilare per x86 / 32 Bit gli argomenti invece che essere passati attraverso lo stack sono passati nei registri! Così la mia bellissima Fill16Asm "poppava" chissà che cosa :D

Così soffrendo come una bestia ho usato una Ubuntu a 32 bit con MonoDevelop e finalmente funzionava come un cavallo...

Ho testato tutti i casi possibili e quello di nostro interesse un buffer di quasi 9 MB viene riempito in 7 ms :eek:

Tutto ingorillato lo provo su Cosmos sicuro al 100% che sarebbe andato alla prima e invece Stack Overflow :cry: :cry: :cry:

De' "La Cosmos Calling Convention"

No, Cosmos non usa CDECL manco un po' (gli argomenti passati sullo stack e il valore di ritorno in EAX):

1. Gli argomenti sono sì sullo stack, ma all'incontrario (il primo argomento è l'ultimo)
2. Il valore di ritorno è scritto al posto dell'ultimo argomento (ovvero l'ultimo :D) se la funzione non aveva argomenti o per esempio aveva un int e si deve ritornare un long (8 byte) lo spazio nello stack si "crea"

Ah povero me usavo pure l'istruzione "ret" pensando - ingenuotto - che fosse la stessa cosa di "return" in C... invece manipolava lo stack come se si usasse chissà quale degli 50 calling convention di x86... e questo faceva a pugni con il nostro metodo per detectare lo stack overflow!

In realtà il punto "2" avviene automaticamente, ma il fatto che gli argomenti andavano messi all'incontrario mi ha lasciato perplesso...

Faccio notare prima che vi emozionate tutti che siamo perfettamente consapevoli che questo non è il modo più veloce per passare parametri / valori di ritorno, questa è solo una versione temporanea poi quando saremo alla versione 1.0 di Cosmos e sarà il momento di ottimizzare per arrivare a essere 20 volte più veloci del C++ (slogan? Probabile :D) ci penseremo in seguito alla giusta stragegia di "bilanciamento" traad registri e stack...

Al momento questa calling convention (CCC) usata è la più vicina alla VM di .Net e questo - di fatto - ci semplifica la vita.

Comunque alla fine ha funzionato come un cavallo tempo su Cosmos: 430 ms!
Beh rispetto a 33 secondi è un ENORME miglioramento, ma perché non ottengo un valore simile a 7 ms?

Ricordatevi che Bochs è una "vera" macchina virtuale e simula anche la CPU... io ho un Core I5, ma lui sta attualmente simulando un Pentium IV quindi in conclusione è tutto OK!

Ora - finalmente - anche la Clear() è quasi istantanea si vede ancora un pochino "designare", ma è accettabile.

Fill() / Memset(), Memcmp(), Memcpy() ovvero la classe MemoryOperations

Prima di tutto qual è la differenza tra Fill() e Memset()? TL;RD la prima fa quello che ti aspetti la seconda no!

La Memset() del C ha questo "grazioso" prototipo:


void *memset(void *s, int c, size_t n);


'int c' è una trappola! Perché viene castato a byte mentre siete distratti quindi se avessi dovuto farlo in C avrei in ogni caso dovuto scrivermela in assembler o chissà quali truschi fare: il Colore blu è un "vero" intero (0x0000FF) :eek:
In C++ sarebbe stato effettivamente meglio visto che la funzione Fill() è fatta con i template e quindi se hai un buffer di interi e 'c' è un intero fa quello che ti aspetti... in C# esiste (esisterà?) Fill() con questo prototipo:


void Fill<T>(T[] buffer, T value)


ma la versione dentro .NET Core usa il for() che ti frega se buffer è troppo grande!

La mia Fill() usando un linguaggio ad oggetti esiste in tante forme questa è quella base che "assomiglia" alla memset():


unsafe public static void Fill(byte* dest, int value, int size)


ci sono overload unsafe sia per puntatori a tipi primitivi che per array di tipi primitivi, il prototipo non usa i tipi "insensati" del C (void *, size_t, int che sono unsigned char :Prrr:) e - ovviamente - non ritorna nulla al massimo andrà in eccezione invece che andare in SEGFAULT.

Oltre che nel mio caso c'è pieno di posti dentro il runtime C# dove Fill() sarebbe utile per esempio:


La Fill dell'Array di cui sopra
Il nuovo tipo Span<T> di C#7 ha anche lui un metodo Fill
L'istruzione IL initblk non è altro che una fill() con value sempre a 0
C'è una ZeroFill() dentro ai sorgenti di Cosmos che non so per cosa sia usata


Il punto 3 è forse il punto "dolente" il modo corretto sarebbe infatti di fare correttamente initblk e molti di quei metodi si ridurrebbero a una chiamata initblk forse è un po' una sorpresa, ma anche le versioni dentro il .Net Framework NON chiamano la initblk, ma si ri-implementato "Fill" spesso più volte.
(spiegazione? La initblk è inefficiente! Perché non riscrivono quella? Boh...)

Le altre due che probabilmente finiranno per chiamarsi Memory.Cmp() e Memory.Copy() servono sicuramente per CGS perché per avere un po' di velocità non ha senso ridisegnare lo schermo tutte le volte, ma devi implementare il double buffering e quindi ti serve un modo veloce per confrontare 2 buffer anche molto grandi e per copiarli!

Memory.Copy() è usata anche nel runtime per esempio ogni volta che si passa un ValueType ad una funzione questo viene copiato (come in C++), il boxing non è altro che la creazione dal "nulla" dell'header dell'oggetto con la copia della parte dati...

Memory.Cmp() forse solo quando si fa l'uguaglianza tra stringhe.

Un punto aperto che devo capire è come dove mettere questa classe (anche il nome mica mi piace molto, ma Memory era già usato) per ora l'ho messo in Core, ma probabilmente dovrebbe essere metodi "intrisechi" di IL2CPU così che possano essere usati un po' ovunque.

Interessante come da pulire lo schermo di blu sia uscito tutto questo casino :D

Net Core

Siamo veramente vicini ad avere un Cosmos che usa Net Core invece di "Net Framework" purtroppo il numero dei plug credo non sia poi molto diminuito, ma per fare bene i plug abbiamo bisogno di uno strumento di analisi esterno per capire davvero quanto lavoro ci sia da fare (IL2CPU ti dice "native method encountered", ma non hai modo per capire quanto tu debba ancora "pluggare" e che magari se lo facevi a basso livello avresti fatto prima!).

Comunque tutti i test passano di nuovo, l'unico problema che stanno avendo è sui template che ti permettono di creare un nuovo kernel che in Net Core sono completamente diversi (la Microsoft ha buttato via il formato XML di VisualStudio per passare ad uno in json), superato questo ostacolo tutto può essere mergiato!

Avere Net Core ci farà procedere molto più speditamente rispetto a Net Framework anche solo la possibilità di vedere i sorgenti liberamente dell'implementazione (compresa quella in C++ / codice nativo) ci semplificherà enormemente la vita.

... mentre Net Core viene portato dentro Net Core tutti gli altri che fanno?

Visto che abbiamo più di 228 potenziali "sviluppatori" (!) dovevamo trovare il modo di "distrarli" mentre Net Core veniva portato dentro Cosmos, ma allo stesso tempo non dovevano esserci attività che si sovrapponevo con Net Core (per esempio non ha senso pluggare Dictionary<T>, magari in Net Core funziona già!) quindi ho identificato 4 attività che potevano essere fatte in parallelo:

https://github.com/CosmosOS/Cosmos/issues/546 (libera)
https://github.com/CosmosOS/Cosmos/issues/545 (in sviluppo)
https://github.com/CosmosOS/Cosmos/issues/544 (libera)
https://github.com/CosmosOS/Cosmos/issues/543 (libera, c'è stato un tentativo di farla, ma ci siamo persi in un loop di "native code encountered" :cry: )
https://github.com/CosmosOS/Cosmos/issues/542 (in sviluppo)

La più degna di nota è che ho seguito più a lungo è 545 ovvero come fare ad avere le informazioni sulla CPU? L'obiettivo finale è avere una classe "ripiena" di proprietà che permetta di implementare su un Cosmos a linea di comando il comando CpuInfo (o se uno è pazzo e vuole fare un sistema POSIX like il "file" /proc/cpuinfo) mentre su una GUI qualcosa di simile a quello che appare premendo il tasto destro su "Il Mio PC" in Windows.

Questo introduce un altro capitolo... un incubo:

SMBIOS ovvero "The Worst is better"

In Cosmos esiste già una classe in Core che non è altro che un wrapper dell'istruzione assembler cpuinfo, non è bellissima forse, ma bastava creare una facade in HAL (o meglio forse dividere in 2 il "motore" in assembler in Core e il codice vero e proprio in HAL) e una in System e via!

Invece no... il ragazzetto ha trovato SMBIOS che ci ha fatto promesse mirabolanti:


Sono "semplici" strutture quindi niente assembler: il codice può essere tutto scritto in HAL tutto in C#!
Sembra la cosa "giusta" visto che funziona anche su ARM, PowerPC ed Itanium (RIP)
Ci da la possibilità di avere un "framework" per avere un sacco di altre informazioni: tipo di BIOS, marca della motherboard, marca della Memoria...


Il primo punto si è rilevato falso le strutture non sono affatto "semplici" intanto non c'è un punto fisso per l'entry point ma bisogna cercare in un range di memoria di 1024 caratteri la stringa "DFI" (:cry:) poi invece di fare come tutte le strutture che ho visto in vita mia in C in cui le "stringhe" sono array di caratteri con un dimensione schiantata in questo caso hanno deciso di fare una cosa "esotica" invece della stringa mettono un byte che è l'indice di una area di memoria che segue la struttura che loro chiamano "non formattata" che non è altro con un bugliolo di byte / caratteri ASCII separati tra di loro dal classico '\0'... il bugliolo di caratteri termina - a sua volta - con un altro '\0'! Fico vero?

Il ragazzo che lo stava sviluppando si lamenta subito contro dei non ben precisati "ingegneri" mandandoli a c*gare direttamente dentro il commit che per computare una lunghezza si deve inventare una nuova "matematica"... dopo mesi scopro il suo errore Bochs come molti progetti Open Source segue la filosofia "The Worst is better" e quindi benché dichiarino di usare la versione X.X e nelle specifiche c'è la parte dati è 21 byte, in realtà implementano la versione vecchia e quindi da leggere ci sono 18 byte... le specifiche comunque sono chiare la versione l'abbiamo messa come "padding" e si deve usare il campo len...
(io che lavoro da anni con queste cose non ci sarei cascato il ragazzo faceva come molti inesperti alcuni anche di ditte a noi "avversarie" leggeva 21 + header in un unico buffer e poi si aspettava di trovare le cose agli offset attesi)

Tutto OK direte voi? Manco per nulla su VmWare si leggono valori sensati su Bochs tutte le stringe sono null / vuote e i valori numeri graziosissimi 0... io speravo che il ragazzo avesse fatto casino o che magari esistesse qualche Kludge per Bochs (magari come molte applicazioni OpenSource ha i default sbagliati e va configurato correttamente), ma purtroppo Ubuntu conferma che è tutto giusto e che SMBIOS non serve ad una mazza:

https://files.gitter.im/CosmosOS/Cosmos/WSCb/illuminatiConfirmed.PNG

perché non solo Bochs fa schifo, ma pare che sia una cosa normale / possa capitare che SMBIOS dica putt*nate per esempio con BIOS cinesi:

http://www.linux-mag.com/id/7768/

Bah io non so che dire davvero... Intel, ARM, IBM, Microsoft... un manuale bello corposo di 350 pagine e poi "Family Other", "Frequency Not Specified", ...!

Quindi? Quindi consideriamoci fortunati: era una "trappola" e meno male che Bochs fa schifo e ce l'ha mostrata prima che prendessimo una "dipendenza" da sto SMBRATTA... certo è un po' brutto dover buttare quasi un mese di lavoro e mica sono sicuro che il povero ragazzo non ha completamente capito che deve cacciare via tutto :(

[1] C'è ancora spazio di ottimizzazione, il for() potrei farlo a blocchi di int (se il resto è divisibile per 4), poi di short e solo alla fine di byte, ma soprattutto nella versione in assembler potrei copiare a blocchi di 64 o 32 facendo "loop unrolling".

cdimauro
01-03-2017, 19:42
Permettimi un'osservazione: non devi essere tu a stravolgere quel loop cercando di velocizzare la Fill e le altre funzioni di memoria. Questa dev'essere roba affidata al compilatore.

Sì, è presto per parlare di ottimizzazioni, lo so, ma voglio dire che non devi perdere prezioso tempo per una cosa che, se tutto ciò che ho letto sarà in buona parte vero, verrà fuori automaticamente / autonomamente grazie ai miglioramenti del backend.

Comunque è importante che tu abbia risolto i problemi che avevi con la definizione e uso dello schermo. E' un grosso passo avanti. Ma sei in grado di selezionare / cambiare al volo una qualunque modalità VESA? Questo è anche molto importante.

fano
01-03-2017, 21:05
Permettimi un'osservazione: non devi essere tu a stravolgere quel loop cercando di velocizzare la Fill e le altre funzioni di memoria. Questa dev'essere roba affidata al compilatore.


Infatti come ho scritto poi nel capitolo che ho aggiunto ora "Fill() / Memset(), Memcmp(), Memcpy() ovvero la classe MemoryOperations" queste operazioni sono così "generiche" che letteralmente non sapevo dove metterle per ora sono in Core, ma avevo intuito che il posto giusto era dentro "IL2CPU"...

O intendi dire che il compilatore dovrebbe essere così furbo da "intuire" che quel for() era la memset() GCC lo fa anche con risultati un po' comici quando beh uno vuole implementare la... memset():

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888

(no non l'hanno risolto è ancora lì pronto a inlooparsi in eterno hanno solo aggiunto un'altro flag ai migliaia già esistenti, il default ovviamente è sbagliato)


Sì, è presto per parlare di ottimizzazioni, lo so, ma voglio dire che non devi perdere prezioso tempo per una cosa che, se tutto ciò che ho letto sarà in buona parte vero, verrà fuori automaticamente / autonomamente grazie ai miglioramenti del backend.


E' probabile sì il fatto è che a parte il colore blu che a me piace perché ricorda il C=64 la Fill() è necessaria perché Bochs lascia lo schermo "sporco" quando si passa in modalità grafica come se cercasse di interpretare il testo precedente come pixel... e far attendere 33 secondi non è bello!

Comunque anche se Fill() finirà un giorno dentro al compilatore il codice l'ho già scritto sarà compito delle ottimizzazioni far sparire lo switch se non serve (magari nel caso fortunato trasformando il tutto in un'assegnazione tra interi), facendo fuori il for se il resto è 0... e lasciando solo l'assembler magari ricopiandolo alla fine in linea come fanno GCC e Clang.

L'implementazione che ho fatto è volutamente "incompleta" visto che come ho detto potevo fare blocchi da 64 e da 32, ma era mio interesse avere qualcosa che funzionasse il prima possibile.


Comunque è importante che tu abbia risolto i problemi che avevi con la definizione e uso dello schermo. E' un grosso passo avanti. Ma sei in grado di selezionare / cambiare al volo una qualunque modalità VESA? Questo è anche molto importante.


In realtà per ora questo funziona solo con Bochs e con gli emulatori che condividono la stessa GPU virtuale (QEMU e VirtualBox) è una versione semplificata di VESA visto che ti permette di fare tutto usando una normale porta di I/O comunque sì posso cambiare risoluzione anche mentre sono in modalità grafica e grazie "al trucco" che alloco più memoria del necessario se lo schermo è più grande il blu c'è sempre! E ti dico di più se disegno un altro oggetto dopo aver cambiato risoluzione questo appare persino (temevo che facesse casino magari con le coordinate).
E Bochs arriva davvero a 1920x1200... semplicemente perché non controlla una fava se fosse per lui anche 0x0 è OK... alcuni risoluzioni pare lo facciano andare pure in SEGFAULT :eek:
Purtroppo ModeInfo non la espongono quindi io ho "hardcodato" tra i modi accettati quelli che hanno più senso (con tanto di schermi 4:3, 5:4, 16:9 e 16:10).

Resto dell'idea che invece la vera perdita di tempo è il driver della VGA legacy cosa serve nel 2017 inoltrato 320x200 a 256 colori o che fa ancora più ridire 640*480 a 16 colori? Il mio schermo va a 1920x1080 e fa 16'000'000 di colori :D

Il mio piano è questo convincere gli utenti a:


Completare CGS mancano ancora dei metodi DrawImage e DrawString
Portare alla "luce" il driver di VmWare che abbiamo pure tra i sorgenti... chissà se funziona: https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.HAL/Drivers/PCI/Video/VMWareSVGAII.cs :D
è di particolare interesse perché validerebbe la "genericità" di CGS e ha già alcune funzionalità accelerate
Un'altra VM interessante da supportare è HiperV anche se sembra complessa se davvero usa solo UEFI
Se davvero la "velocità" è così importante possono provare ad implementare un double buffer, ma dentro al driver non a livello utente come ho visto in alcuni kernel Cosmos :D
A quel punto uno potrebbe creare un "modalità testuale" più bella evitando gli incubi delle codepage usando direttamente UTF-16... l'Arabo che si scrive all'incontrario e con le legature resta un incubo! Infatti Linux mica è capace...
Potresti pure aprire un ImageViewer "grezzo" cosa che con Linux in modalità testuale ti scordi perché hai bisogno di X per mostrare "finestre"
Cosmos Widget Toolkit magari?
Il vero VESA con tanto di emulatore 8086 di cui ben sai (a proposito a che punto sei?)


Tutto questo ha senso "relativo" visto che Cosmos manco ha il garbage collector quindi primo o poi la macchina Virtuale se ne accorge e andrà in Core immagino :D

Riguardo a SMBIOS invece? Perché è una "trappola"? Non c'è proprio altra possibilità che usare l'assembler a questo punto vero?

Ah ho visto che parlavate di X# il fatto che è verboso è dovuto in realtà al fatto che manca in Visual Studio / Roslyn il modo di "embeddare" un altro linguaggio dentro C# sarebbe utile non solo nel nostro caso, ma uno potrebbe volere embeddare per esempio F# o VB.NET dentro C# o IL in linea (l'equivalente nel mondo .NET di quando in GCC si butta assembler dentro un sorgente C), il vero X# è molto più coinciso:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Debug.DebugStub/Screen.xs#L9

ma appunto non può essere embeddato dentro C#!
(ma forse un giorno lo faranno c'è un issue aperta alla Microsoft speriamo che ci pensino seriamente)

Abbiamo bisogno della nostra "versione" di assembler anche per un altro motivo attualmente X# è "transpilato" in assembler NASM, ma questo è temporaneo dovremo un giorno scrivere il nostro assembler per quando avremo le applicazioni dentro Cosmos (che prima di essere eseguite andranno compilate ovviamente).

cdimauro
02-03-2017, 05:13
Infatti come ho scritto poi nel capitolo che ho aggiunto ora "Fill() / Memset(), Memcmp(), Memcpy() ovvero la classe MemoryOperations" queste operazioni sono così "generiche" che letteralmente non sapevo dove metterle per ora sono in Core, ma avevo intuito che il posto giusto era dentro "IL2CPU"...

O intendi dire che il compilatore dovrebbe essere così furbo da "intuire" che quel for() era la memset() GCC lo fa anche con risultati un po' comici quando beh uno vuole implementare la... memset():

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888

(no non l'hanno risolto è ancora lì pronto a inlooparsi in eterno hanno solo aggiunto un'altro flag ai migliaia già esistenti, il default ovviamente è sbagliato)
Con la differenza che lì era la memset che tentava di richiamare se stessa, mentre per le tue funzioni sarebbe il backend del compilatore che si accorge del loop semplice, ed emette codice apposito, che non ne necessariamente sia una chiamata a funzione specializzata.

Da Haswell in poi le istruzioni "di stringa" (quelle complesse / legacy introdotte con l'8086 :D) sono state notevolmente velocizzate, e bastano 2-3 byte in totale per usarle: meno di una call. ;)
E' probabile sì il fatto è che a parte il colore blu che a me piace perché ricorda il C=64 la Fill() è necessaria perché Bochs lascia lo schermo "sporco" quando si passa in modalità grafica come se cercasse di interpretare il testo precedente come pixel... e far attendere 33 secondi non è bello!

Comunque anche se Fill() finirà un giorno dentro al compilatore il codice l'ho già scritto sarà compito delle ottimizzazioni far sparire lo switch se non serve (magari nel caso fortunato trasformando il tutto in un'assegnazione tra interi), facendo fuori il for se il resto è 0... e lasciando solo l'assembler magari ricopiandolo alla fine in linea come fanno GCC e Clang.

L'implementazione che ho fatto è volutamente "incompleta" visto che come ho detto potevo fare blocchi da 64 e da 32, ma era mio interesse avere qualcosa che funzionasse il prima possibile.
OK, se l'hai scritto, lascialo. Ma non ci perdere altro tempo.
In realtà per ora questo funziona solo con Bochs e con gli emulatori che condividono la stessa GPU virtuale (QEMU e VirtualBox) è una versione semplificata di VESA visto che ti permette di fare tutto usando una normale porta di I/O comunque sì posso cambiare risoluzione anche mentre sono in modalità grafica e grazie "al trucco" che alloco più memoria del necessario se lo schermo è più grande il blu c'è sempre! E ti dico di più se disegno un altro oggetto dopo aver cambiato risoluzione questo appare persino (temevo che facesse casino magari con le coordinate).
E Bochs arriva davvero a 1920x1200... semplicemente perché non controlla una fava se fosse per lui anche 0x0 è OK... alcuni risoluzioni pare lo facciano andare pure in SEGFAULT :eek:
Purtroppo ModeInfo non la espongono quindi io ho "hardcodato" tra i modi accettati quelli che hanno più senso (con tanto di schermi 4:3, 5:4, 16:9 e 16:10).
So come funziona Bochs. Ma se non espone nemmeno il ModeInfo è una vera ciofeca. Considerato tutto il tempo che c'ha perso, perché non passi direttamente a VMWare, che ha un'emulazione MOLTO più accurata?
Resto dell'idea che invece la vera perdita di tempo è il driver della VGA legacy cosa serve nel 2017 inoltrato 320x200 a 256 colori o che fa ancora più ridire 640*480 a 16 colori? Il mio schermo va a 1920x1080 e fa 16'000'000 di colori :D
Lascia perdere anche questo: vai di VESA e basta. Non ha alcun senso buttare tempo per supportare la VGA (classe 1987!!!).
Il mio piano è questo convincere gli utenti a:


Completare CGS mancano ancora dei metodi DrawImage e DrawString
Portare alla "luce" il driver di VmWare che abbiamo pure tra i sorgenti... chissà se funziona: https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.HAL/Drivers/PCI/Video/VMWareSVGAII.cs :D
è di particolare interesse perché validerebbe la "genericità" di CGS e ha già alcune funzionalità accelerate
Un'altra VM interessante da supportare è HiperV anche se sembra complessa se davvero usa solo UEFI
Se davvero la "velocità" è così importante possono provare ad implementare un double buffer, ma dentro al driver non a livello utente come ho visto in alcuni kernel Cosmos :D
A quel punto uno potrebbe creare un "modalità testuale" più bella evitando gli incubi delle codepage usando direttamente UTF-16... l'Arabo che si scrive all'incontrario e con le legature resta un incubo! Infatti Linux mica è capace...
Potresti pure aprire un ImageViewer "grezzo" cosa che con Linux in modalità testuale ti scordi perché hai bisogno di X per mostrare "finestre"
Cosmos Widget Toolkit magari?
Il vero VESA con tanto di emulatore 8086 di cui ben sai (a proposito a che punto sei?)

Ho cambiato lavoro e arrivo a casa abbastanza stanco in questo periodo: l'ultima cosa che m'interessa è buttarmi sui miei progetti. Ma la situazione va migliorando, mi sto integrando, un sacco di cose le ho imparate, e quindi prevedo di rimettermi a smanettare fra qualche tempo.

Delle cose che hai detto lascerei perdere completamente il supporto all'Hyper-V. E i idem il double buffer, visto che ormai ti funziona tutto sufficientemente.

Mentre al momento lascerei perdere anche l'UTF-16: l'ASCII / Latin-1 va benissimo per un s.o. ancora in sviluppo.
Tutto questo ha senso "relativo" visto che Cosmos manco ha il garbage collector quindi primo o poi la macchina Virtuale se ne accorge e andrà in Core immagino :D

Riguardo a SMBIOS invece? Perché è una "trappola"? Non c'è proprio altra possibilità che usare l'assembler a questo punto vero?
Non lo conosco, e non so come si usa, per cui non ti saprei dire. :stordita:
Ah ho visto che parlavate di X# il fatto che è verboso è dovuto in realtà al fatto che manca in Visual Studio / Roslyn il modo di "embeddare" un altro linguaggio dentro C# sarebbe utile non solo nel nostro caso, ma uno potrebbe volere embeddare per esempio F# o VB.NET dentro C# o IL in linea (l'equivalente nel mondo .NET di quando in GCC si butta assembler dentro un sorgente C), il vero X# è molto più coinciso:

https://github.com/CosmosOS/Cosmos/blob/master/source/Cosmos.Debug.DebugStub/Screen.xs#L9

ma appunto non può essere embeddato dentro C#!
(ma forse un giorno lo faranno c'è un issue aperta alla Microsoft speriamo che ci pensino seriamente)

Abbiamo bisogno della nostra "versione" di assembler anche per un altro motivo attualmente X# è "transpilato" in assembler NASM, ma questo è temporaneo dovremo un giorno scrivere il nostro assembler per quando avremo le applicazioni dentro Cosmos (che prima di essere eseguite andranno compilate ovviamente).
Se fosse possibile, al momento userei direttamente l'assembly con NASM, da linkare poi col vostro codice. Davvero, con X# non ci lavorerei mai: troppo, troppo prolisso.

fano
02-03-2017, 09:14
Con la differenza che lì era la memset che tentava di richiamare se stessa, mentre per le tue funzioni sarebbe il backend del compilatore che si accorge del loop semplice, ed emette codice apposito, che non ne necessariamente sia una chiamata a funzione specializzata.


Ma in che senso "emette" codice? Cioè GCC / Clang hanno un'implemtazione interna di memset()/memcmp()/memcpy() giusto?

Io credevo che effettivamente usassero quelle ed il fatto che poi nell'assembler generato ne vedessi solo un pezzetto fosse dovuto ai passi di ottimizzazione invece come fanno ad arrivare a questo?

https://godbolt.org/g/RuS5Bd


Da Haswell in poi le istruzioni "di stringa" (quelle complesse / legacy introdotte con l'8086 :D) sono state notevolmente velocizzate, e bastano 2-3 byte in totale per usarle: meno di una call. ;)


Ma le istruzioni stringa non copiano comunque a blocchi d'interi (byte, word, doubleword o su x64 quadword)? Quindi usare comunque i registri XMM e copiare a botte di 16 Byte o meglio ancora di 32 o 64 non è in ogni caso più veloce?
Il fatto che il compilatore Intel non le usi, ma usi il mio metodo mi fa pensare che sia meglio...


OK, se l'hai scritto, lascialo. Ma non ci perdere altro tempo.


No dal mio punto di vista il lavoro su CGS è per ora finito lo diamo "in bocca" ai famelici users e vediamo cosa ne combinano :D


So come funziona Bochs. Ma se non espone nemmeno il ModeInfo è una vera ciofeca. Considerato tutto il tempo che c'ha perso, perché non passi direttamente a VMWare, che ha un'emulazione MOLTO più accurata?


Sì tra le "funzioni" esposte con la IOPort c'è ben poco cambio modo (che manco da la possibilità di ritornare in modalità testuale :muro: ), disegna un pixel e poco altro...

Vedi l'utilità di Bochs io la vedo in due cose:


Il fatto che possa emulare praticamente ogni CPU x86 esistente e anche via configurazione "inventarmi" CPU particolari tipo un 486 con AVX
Il debugger integrato che mi permette di vedere quali valori sono dentro ai registri, utile soprattutto se uno è ancora inesperto di Assembler come me e scrive codice "a caso". VmWare in quei casi si stronca brutalmente


Poi visto che il target principale di Cosmos - almeno per adesso sono le VM - è chiaro che vanno supportate tutte e in particolare VmWare (in fondo è quella più usata) che - infatti - a parte la grafica è perfettamente supportato da Cosmos e i nostri Unit Test sono già predisposti per testare ambedue le VM.

Poi il tempo che ci ho perso è più dovuto alla mia voglia di "smanettare" e all'immaturità del runtime che altro il driver (quello di basso livello) Bochs / VBE esisteva già e funzionava pure!


Lascia perdere anche questo: vai di VESA e basta. Non ha alcun senso buttare tempo per supportare la VGA (classe 1987!!!).


Mi fa piacere che sto ragionando nella maniera corretta... non ha più senso supportarlo è troppo "antico", meglio concentrarci su VESA :D


Ho cambiato lavoro e arrivo a casa abbastanza stanco in questo periodo: l'ultima cosa che m'interessa è buttarmi sui miei progetti. Ma la situazione va migliorando, mi sto integrando, un sacco di cose le ho imparate, e quindi prevedo di rimettermi a smanettare fra qualche tempo.


OK, nel frattempo ho cercato emulatori x86 che - teoricamente - dovrebbero essere stati creati per lo stesso scopo (cioè emulare 8086 per far funzionare VESA) ed ho trovato quello che dovrebbe essere usato da X:

https://github.com/wfeldt/libx86emu

la licenza è pure BSD quindi compatibile con Cosmos, ma - purtroppo - il codice fa alquanto schifo un bel filone (non di pane, ma un grosso "file") da un milione di righe fatto a botte di copia & incolla:
https://github.com/wfeldt/libx86emu/blob/master/ops.c

perché il codice scritto in C ha la tendenza a fare sempre così schifo? Io un po' al C la colpa la do non "forzando" la struttura ad uno viene naturale fare ste porcate... ciò non toglie che - sforzandosi - un pochino anche in C le cose possono esser fatte meglio!
Le funzioni - almeno quelle - in C le hanno fatte :D

Mi chiedo, ma serve tutta quella roba o per parlare con VESA si può implementare un sub-set? Il tuo sarà un emulatore completo di 8086 come questo oppure qualcosa di più semplice?

Ci sono altri casi in cui ha senso emulare 8086 in un sistema operativo? Esiste qualche altro layer "sfigato" come VESA che funziona solo in "Real Mode" a 16 Bit?


Delle cose che hai detto lascerei perdere completamente il supporto all'Hyper-V. E i idem il double buffer, visto che ormai ti funziona tutto sufficientemente.


Delle elenco che ho postato io mi occuperei solo della coordinazione, l'intenzione è che io torni ad occuparmi delle cose a basso livello... la cosa più ungente è avere questo "Plug Inspector" io vorrei riuscire entro la fine del 2017 (l'anno di Cosmos :D) ad avere almeno tutte le classi della BCL funzionanti altrimenti molto spesso ti trovi a scrivere quasi in C++ / Java il che non è bello (potremmo chiamarlo C# 0 :D).

Il lavoro su HiperV è in realtà già iniziato, il problema sembra essere nel modo diverso in cui ti danno a disposizione la debug console e che sta creando qualche problema:

https://github.com/CosmosOS/Cosmos/pull/550


Mentre al momento lascerei perdere anche l'UTF-16: l'ASCII / Latin-1 va benissimo per un s.o. ancora in sviluppo.


Per ora sulla Console in modalità testuale in realtà viene supportato solo ASCII a me da un po' noia avere la possibilità di settare la tastiera con la keymap italiana e poi ottenere caratteri strani invece che 'è'... mi ricorda troppo Linux questo :D

La modifiche da fare sono poca roba in realtà la stringa C# viene trasformata in un array di Char e ogni singolo Char viene "violentemente" castato a Byte ovviamente in questo modo solo i caratteri ASCII sopravvivono si devono semplicemente chiamare le funzioni di encode / decode di C# e tutto dovrebbe funzionare.

Il discorso di avere il Terminale come "Terminale Virtuale" (cioè fatto in modalità grafica) richiede di sicuro più tempo però visto che ora abbiamo 228 potenziali sviluppatori e fare "grafica" è una cosa che di sicuro potrebbe invogliarli di più a collaborare è "il primo blocco" per avere un sistema operativo "Desktop" (che a me interessa relativamente... a me interessa avere più gli Widget visto che le mie GUI sono sempre kioscate).


Non lo conosco, e non so come si usa, per cui non ti saprei dire. :stordita:


Peccato speravo potessi darci qualche "dritta"! Non sai se esistono modi alternativi per avere informazioni sulla CPU a parte usare l'istruzione cpuinfo?


Se fosse possibile, al momento userei direttamente l'assembly con NASM, da linkare poi col vostro codice. Davvero, con X# non ci lavorerei mai: troppo, troppo prolisso.

Dai la funzione Cls() nel file che ti ho mostrato non puoi dire che è verbosa è più o meno simile a quello che faresti in C (se potessi farlo)...

Se usassimo direttamente il "dialetto" di Assembler usato da NASM quando Cosmos dovrà diventare "self hosting" dovremmo o fare una versione di NASM in C# (brr...) o riscrivere tutto l'Assembler usando X#.

Provo a fare un po' di "mobbing" per convincere la Microsoft a dare la possibilità di embeddare altri linguaggi dentro C#, devo solo ritrovare l'issue :D

fano
04-03-2017, 15:16
Vediamo se si riesce ad aver questo in C# 7.x / 8.0:

https://github.com/dotnet/csharplang/issues/226

fano
13-03-2017, 08:40
Ciao a tutti!

Questa domenica ho cercato di organizzare un po' i lavori futuri e mi è uscita questa lista di cose da aggiungere a CGS: https://github.com/CosmosOS/Cosmos/issues/601.

Però continuo a rimuginarci sopra e non sono sicuro in particolare di alcuni elementi:

1. Disegnare un'immagine è parte di CGS? O potrebbe essere una cosa già di alto livello che dovrebbe essere fatto da uno widget toolkit (che con molta fantasia potrebbe chiamarsi CWTK - Cosmos Widget Tool Kit :D)?
2. Disegnare testo è parte di CGS? Questo sembra davvero un casino se si pensa di usare il prototipo di System.Drawing: ti porti dietro il concetto di Font (banalmente come faccio a sapere dove nel OS sono i file dei font?) e si vuoi usare lo standard de facto TrueType scopri che dentro ai font c'è una macchina virtuale...

Ho bisogna anche del vostro aiuto riguardo questa issue: https://github.com/CosmosOS/Cosmos/issues/604

fano
25-06-2017, 13:25
Salve a tutti!

Finalmente ci siamo:

Il "Core" di Cosmos

Dopo tanto soffrire il porting di Cosmos su Net Core è fatto!
https://github.com/CosmosOS/Cosmos/releases/tag/Userkit_20170620

Io non ho partecipato direttamente ai lavori, ma il grosso dei problemi non stati tanto per il "porting", ma per il fatto che .Net Core usa un nuovo sistema per i progetti che è stato cambiato in corso d'opera 2 - 3 volte da Microsoft (prima volevano usare file .json, poi ci hanno ripensato e sono tornati all'xml quasi uguale a quello "legacy", ma sempre incompatibile) costringendoci a ricominciare da capo!
Un'altra grossa difficoltà che abbiamo avuto è l'integrazione con Visual Studio che è una fi*ata pazzesca quando funziona debuggare un SO con Visual Studio non ha davvero prezzo, però il problema è che per fare questo bisogna lanciare durante l'installazione uno script .bat che genera i template, le extensions per VS, ecc...
Infatti noterete che ne abbiamo rilasciato 2 di UserKit: il primo non era mica venuto :cry:

The Wikipedia conspiracy

Era un 29 Aprile ed ero bello paciarotto che sonnecchiavo pensando al glorioso futuro in cui Cosmos avrebbe fatto funzionare lavatrici, frigoriferi, astronavi quando leggo questo:

https://github.com/CosmosOS/Cosmos/issues/629

Le motivazioni di Wiki sono beh "peurili" a dir poco si riassume nella seguente frase "X# non esiste".
Il mio tentativo di portare prove che X# effettivamente esiste è tacciato di Canvassing:
https://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletion/X_Sharp
cosa diavole è?
Boh... alla fine non vogliono sentir ragioni e chiudono l'articolo!
Perché mai vi chiederete? Per questo:
https://en.wikipedia.org/wiki/XSharp

questi non solo ci hanno fregato il nome (!), ma pure la pagina su Wiki!
Secondo me - alla fine - Wiki non è "libera" quanto vuol far credere.

Ma non tutto il male vien per nuocere vero?
Due cose positive sono nate da questo:


X# può essere utile anche da altri è "high level assembler" e non ha realmente alcun legame con Cosmos! Un giorno X# diventerà un progetto separato e ritornerà su Wiki con fulgore: promesso
Dobbiamo avere il nostro sito funzionante


Go Cosmos Go!
... ed infatti eccolo qua in tutta la sua gloria:
http://www.gocosmos.org/

ovviamente c'è la documentazione di X# che Wiki ha scancellato:
http://www.gocosmos.org/docs/xsharp/

ma come vedete c'è anche molto altro in parte travasato da GitHub visto che - in fondo - non è che possiamo fidarci molto nemmeno di loro, magari si svegliano e "falliscono" / "chiudono" e siamo nella bratta...

In futuro credo che dovremo anche aggiungere un forum per certo (la chat di Git è spesso troppo dispersiva) avete altri suggerimenti?

CGS fa progressi

In questo caso un immagine è meglio di mille parole giusto?
Eccovela:

https://s14.postimg.org/axnfd41v1/Cosmos_CGS_Progress.png (https://postimg.org/image/axnfd41v1/)

Quel triangolo mi sa che l'avrei disegnato meglio io a mano (e no non sono Giotto, son più sul genere Schifani)... credo manchi un controllo sui vertici per capire se possano davvero creare un triangolo :p
Sicuramente c'è qualche formula matematica per questo...

DrawImage() e DrawString() sono invece ancora ferme "con le quattro frecce" il fatto è che Canvas è pensato per i metodi che possono essere accelerati in hardware e probabilmente disegnare un'immagine avviene sempre in software o no? Per immagine io intendo non una JPEG o PNG ovviamente, ma la rappresentazione non compressa quindi una semplice BMP! Ma non sono ancora convinto di questo sinceramente... cosa ne pensate?

Scrivere il testo "seriamente" non è una cosa da "signorine" quindi su questo sono convinto che ci vorrà un altra libreria di più alto livello che si smanazza i font truetype, fa tutte le cose "folli" tipografiche per "disegnare" la stringa ecc...

Le 89 "soluzioni" di Cosmos

Il "proprietario" di Cosmos è tornato (!) e non ha gradito molto che Visual Studio facesse passare ben 15 minuti a caricare la soluzione gigantesca che è Cosmos così ha deciso che andava letteralmente fatta a pezzi!
Non so davvero il numero finale ottenuto è 89, ma almeno 8 soluzioni mi sa che son venute.
Direi che era pure l'ora di farlo sto lavoro... di sicuro non era un buon biglietto da visita come era prima la situazione.

L'Ispettore dei Plug
Visto che ora la situazione è stabile (Cosmos compila di nuovo!) ho deciso di riprendere il lavoro sul "Plug Inpector" cito dalla nostra road map:

Plug Tool

IL2CPU should fail if it encounters a plug that isn’t matched/used
Some code exists already as a ilspy plugin, start there
Select an item, generate plug shell to clipboard. Later on to plug source project.
Scan a project, show all existing plugs
Scan a project, show all things that NEED plugged

Abbiamo deciso che il punto di partenza è avere una libreria che genera un file XML l'attuale "Plug Inspector" (non quello integrato in ILSPY) è una normale applicazione Winform che non solo si occupa della presentazione dei dati, ma anche di estrarli questo è poco pratico visto che Cosmos anche se va considerato "future" sarà sicuramente compilabile anche su Mac OS e se uno è masochista pure su Linux... forse proprio usando Visual Studio Code e quindi potremo usare anche altri sistemi per mostrare le informazioni per esempio una form ASP.Net o Avalonia (una versione portabile di WPF).

Per adesso è tutto aspetto i vostri commenti :D

GTKM
30-06-2017, 18:24
"Abbiamo deciso che il punto di partenza è avere una libreria che genera un file XML l'attuale "Plug Inspector" (non quello integrato in ILSPY) è una normale applicazione Winform che non solo si occupa della presentazione dei dati, ma anche di estrarli questo è poco pratico visto che Cosmos anche se va considerato "future" sarà sicuramente compilabile anche su Mac OS e se uno è masochista pure su Linux... forse proprio usando Visual Studio Code e quindi potremo usare anche altri sistemi per mostrare le informazioni per esempio una form ASP.Net o Avalonia (una versione portabile di WPF)."

Ma non si può proprio estirpare XML dalla faccia della Terra, nei secoli dei secoli?

Comunque, bene il sito, ci voleva proprio! 'sto Visual Studio Community si può usare per CosmOS o no? Qua ci volete tutti con Vim mi sa! :D

cdimauro
30-06-2017, 19:23
Mi spiace ma, causa scarsissimo tempo rimasto, ho sostanzialmente abbandonato il forum. Ogni tanto mi arrivano le notifiche ai thread a cui sono sottoscritto, e quando posso guardo i nuovi messaggi, ma finisce lì.

In bocca al lupo per il progetto.

fano
01-07-2017, 12:55
"Abbiamo deciso che il punto di partenza è avere una libreria che genera un file XML l'attuale "Plug Inspector" (non quello integrato in ILSPY) è una normale applicazione Winform che non solo si occupa della presentazione dei dati, ma anche di estrarli questo è poco pratico visto che Cosmos anche se va considerato "future" sarà sicuramente compilabile anche su Mac OS e se uno è masochista pure su Linux... forse proprio usando Visual Studio Code e quindi potremo usare anche altri sistemi per mostrare le informazioni per esempio una form ASP.Net o Avalonia (una versione portabile di WPF)."

Ma non si può proprio estirpare XML dalla faccia della Terra, nei secoli dei secoli?


Beh ormai XML si è affermato come mezzo di "intercomunicazione" tra processi... l'alternativa sarebbe json, ma non è così ben "integrato" con C#...
Mi ha piacevolmente sorpreso come sia "banale" serializzare una classe in C# e fare l'inverso se penso a come ho sofferto a fare le stesse cose in C con la brattosa libXML2 :cry:


Comunque, bene il sito, ci voleva proprio! 'sto Visual Studio Community si può usare per CosmOS o no? Qua ci volete tutti con Vim mi sa! :D

Certo che si può usare: io la uso regolarmente :D
Mi raccomando la versione 2017, il 2015 non è più supportato da Cosmos!

La questione di Visual Studio Code io ho cercato di "bloccarla" quello sì che sembra quasi GVIM (beh dai un po' meglio lo è!).

GTKM
01-07-2017, 13:58
Beh ormai XML si è affermato come mezzo di "intercomunicazione" tra processi... l'alternativa sarebbe json, ma non è così ben "integrato" con C#...
Mi ha piacevolmente sorpreso come sia "banale" serializzare una classe in C# e fare l'inverso se penso a come ho sofferto a fare le stesse cose in C con la brattosa libXML2 :cry:

Da quel po' che ho letto di sfuggita, mi pare che libxml2 sia una roba un filino buggata.
Per il resto, beh, speriamo che un giorno si riesca ad eliminare XML. :D


Certo che si può usare: io la uso regolarmente :D
Mi raccomando la versione 2017, il 2015 non è più supportato da Cosmos!

La questione di Visual Studio Code io ho cercato di "bloccarla" quello sì che sembra quasi GVIM (beh dai un po' meglio lo è!).

Beh, l'unico motivo per usare Vim è la possibilità di farci tutto con shortcuts da tastiera. Quale sia l'utilità di GVIM non mi è ben chiaro.

Visual Studio Code è un editor di testo sotto steriodi. Non so perché l'abbiano fatto, ma tant'è.

Comunque tempo fa mi pare mi avessi detto che la versione Community di VS non fosse supportata, per quello ho chiesto, ma forse avevo capito male io. :D

fano
01-07-2017, 14:16
L'unico vantaggio di GVIM rispetto a VIM è che essendo con GUI posso tenere aperto più di un file contemporaneamente insomma il "multitasking" roba da far tremare le ginocchia!
Io a volte visto che trovo "disordinato & incomprensibile" come si dovrebbe lavorare su Linux ne ho aperte 89 copie... a volte con file aperti anche più volte
e quell'aborto inizia a creare quegli inutile file .swp... che schifo di modo di lavorare!

Capisci che il fatto che dopo 15 anni che esiste XML, libxml2 sia "ancora un po' bacata" è preoccupante dai... ma poi lasciamo stare bacata o non bacata con C# creo le classi e gli dico "serialize" e via ho il mio XML bello e fatto con libxml2 devo farmelo direttamente a mano...

Addirittura avendo l'XSD c'è un tool che ti crea le classi direttamente: https://docs.microsoft.com/en-us/dotnet/framework/serialization/xml-schema-definition-tool-xsd-exe

Mah poi io ho colleghi che preferiscono farsi l'XML a botte di sprintf()... ma quelli sono pazzi lasciamo perdere :D

Io vorrei eliminare il C non XML, comunque non so se si era... intuito :D

Comunque se vuoi / volete collaborare al progetto:
http://www.gocosmos.org/download/

GTKM
01-07-2017, 15:38
L'unico vantaggio di GVIM rispetto a VIM è che essendo con GUI posso tenere aperto più di un file contemporaneamente insomma il "multitasking" roba da far tremare le ginocchia!
Io a volte visto che trovo "disordinato & incomprensibile" come si dovrebbe lavorare su Linux ne ho aperte 89 copie... a volte con file aperti anche più volte
e quell'aborto inizia a creare quegli inutile file .swp... che schifo di modo di lavorare!

Capisci che il fatto che dopo 15 anni che esiste XML, libxml2 sia "ancora un po' bacata" è preoccupante dai... ma poi lasciamo stare bacata o non bacata con C# creo le classi e gli dico "serialize" e via ho il mio XML bello e fatto con libxml2 devo farmelo direttamente a mano...

Addirittura avendo l'XSD c'è un tool che ti crea le classi direttamente: https://docs.microsoft.com/en-us/dotnet/framework/serialization/xml-schema-definition-tool-xsd-exe

Mah poi io ho colleghi che preferiscono farsi l'XML a botte di sprintf()... ma quelli sono pazzi lasciamo perdere :D

Io vorrei eliminare il C non XML, comunque non so se si era... intuito :D

Comunque se vuoi / volete collaborare al progetto:
http://www.gocosmos.org/download/
Beh dai, Emacs con 5-6 plugin è una potenza, il problema è arrivare ad una configurazione buona (un classico...). Immagino che con Vim sia uguale.

Per il resto, già sai che ci sono un sacco di cose vecchie e ancora bacate, ne abbiamo discusso estensivamente ahah :D
XML a colpi di sprintf () ha un non so che di romantico... :D

Al momento sono impelagato in una libreria multithreaded in C. Mutex come se non ci fosse un domani.

Sent from my HUAWEI VNS-L31 using Tapatalk

fano
01-07-2017, 17:37
Beh dai, Emacs con 5-6 plugin è una potenza, il problema è arrivare ad una configurazione buona (un classico...). Immagino che con Vim sia uguale.


Mah purtroppo sono scelte aziendali... mai usato Emacs, ma conoscendomi mi farebbe schifo pure quello! Io voglio poter usare un IDE... mi accontento pure di Eclipse (no QtCreator mi ha fatto rimpiangere GVIM), ma non si può nel 2017 inoltrato continuare ad usare GVIM + Make da linea di comando dai!

Pensa alla cosa assurda che il cliente (che è il proprietario dei sorgenti) ci ha espressamente richiesto che lavorassimo con Eclipse visto che - purtroppo - vogliono metterci le mani anche loro nel codice (:eek: ) e la gente normale di fare Make sul terminale non vuole nemmeno sentirne parlare... beh abbiamo trovato un "trusco" che permette ad Eclipse di pupparsi i Makefile e noi si continua come negli anni '60 col nostro bravo GVIM e Make :cry:


Per il resto, già sai che ci sono un sacco di cose vecchie e ancora bacate, ne abbiamo discusso estensivamente ahah :D
XML a colpi di sprintf () ha un non so che di romantico... :D


Romantico sì... basta che quando inizia ad andare in core ogni 2 per 3 non debba essere io a debuggare quello schifo :D
La scusa? Eh ma VxWorks mica la supporta la libxml2 dai... pensa che io in una settimana ho portato:

1. json-c
2. libreria "wrapper" scritta da noi che rende safe json-c
3. libxml2 (!)
4. libreria "wrapper" scritta da noi che rende safe libxml2
5. Posix thread (simulati come task VxWorks non erano totalmente "compliant" visto che non avevano memory leak quando venivano terminati brutalmente)
6. Libreria nostra che doveva interfaccia via XML con un POS

funzionava come un cavallo certo un po' lento sempre di un Motorola 68000 si parla eh... poi quando l'hanno vista funzionare mi hanno detto che ci hanno ripensato :muro:


Al momento sono impelagato in una libreria multithreaded in C. Mutex come se non ci fosse un domani.


Multithread in C? E cos'hai fatto di male per meritartelo? Poveretto...

Alla fine sbattendo mutex a destra e a sinistra si ottiene la cosa ridicola che solo un thread può girare e tutti gli altri sono bloccati sul mutex proprio utile vero?
Occhio che i mutex vanno anche rilasciati ed è facile scordarselo nei casi di errore... e pthread_exit() a differenza di exit() ha un piccolo "baco": non rilascia la memoria / risorse usate dal thread!

GTKM
01-07-2017, 18:32
Mah purtroppo sono scelte aziendali... mai usato Emacs, ma conoscendomi mi farebbe schifo pure quello! Io voglio poter usare un IDE... mi accontento pure di Eclipse (no QtCreator mi ha fatto rimpiangere GVIM), ma non si può nel 2017 inoltrato continuare ad usare GVIM + Make da linea di comando dai!

Pensa alla cosa assurda che il cliente (che è il proprietario dei sorgenti) ci ha espressamente richiesto che lavorassimo con Eclipse visto che - purtroppo - vogliono metterci le mani anche loro nel codice (:eek: ) e la gente normale di fare Make sul terminale non vuole nemmeno sentirne parlare... beh abbiamo trovato un "trusco" che permette ad Eclipse di pupparsi i Makefile e noi si continua come negli anni '60 col nostro bravo GVIM e Make :cry:

Emacs con i giusti "plug-in" diventa "produttivo" (per gli amanti :D).
Io mi trovo bene con QtCreator ma malissimo con Eclipse per il C. Un disastro proprio, non "trova" nemmeno la libreria standard nonostante abbia controllato tutti i Path.



Romantico sì... basta che quando inizia ad andare in core ogni 2 per 3 non debba essere io a debuggare quello schifo :D
La scusa? Eh ma VxWorks mica la supporta la libxml2 dai... pensa che io in una settimana ho portato:

1. json-c
2. libreria "wrapper" scritta da noi che rende safe json-c
3. libxml2 (!)
4. libreria "wrapper" scritta da noi che rende safe libxml2
5. Posix thread (simulati come task VxWorks non erano totalmente "compliant" visto che non avevano memory leak quando venivano terminati brutalmente)
6. Libreria nostra che doveva interfaccia via XML con un POS

funzionava come un cavallo certo un po' lento sempre di un Motorola 68000 si parla eh... poi quando l'hanno vista funzionare mi hanno detto che ci hanno ripensato :muro:

Almeno ti sei allenato :D


Multithread in C? E cos'hai fatto di male per meritartelo? Poveretto...

Alla fine sbattendo mutex a destra e a sinistra si ottiene la cosa ridicola che solo un thread può girare e tutti gli altri sono bloccati sul mutex proprio utile vero?
Occhio che i mutex vanno anche rilasciati ed è facile scordarselo nei casi di errore... e pthread_exit() a differenza di exit() ha un piccolo "baco": non rilascia la memoria / risorse usate dal thread!

Eh, è una libreria attualmente attivamente usata per la ricerca. Devo terminare alcune cose e scrivere un articolo col mio prof per proporlo per una conferenza internazionale.
Con le pthread devo ammettere che mi sto trovando malissimo, ma forse sono io, buh.
Il problema grosso è che sono partito da un programma già scritto malissimo, singlethreaded. Quindi immagina. Ho dovuto deallocare tutte le risorse che i geniacci facevano allocare, e tutto il resto.

Io mi trovo bene con C e riga di comando, anche se il progetto è grosso. Quello che non digerisco sono le cose scritte a cazzo di cane.

Appena finisco mi studio CosmOS e .NET in maniera approfondita. :D

Sent from my HUAWEI VNS-L31 using Tapatalk

fano
01-07-2017, 21:17
Mi spiace ma, causa scarsissimo tempo rimasto, ho sostanzialmente abbandonato il forum. Ogni tanto mi arrivano le notifiche ai thread a cui sono sottoscritto, e quando posso guardo i nuovi messaggi, ma finisce lì.


Anch'io in questo periodo sono molto preso con il lavoro! Spero un giorno tu abbia di nuovo tempo per il forum.

Posso aggiungere un nuovo capitolo solo per te:

The incredible stench of GPL

Un ragazzetto proprio uno o 2 giorni dopo che ho postato il qui se ne esce di aver trovato della "bratta" GPL dentro i sorgenti di Cosmos e che eravamo in qualche sorta di "violazione"!
Pretende pure che noi si aggiunga la frasetta del GPL al nostro progetto:

https://github.com/CosmosOS/Cosmos/pull/679/files

per fortuna usiamo solo degli exe e quindi il ragazzetto viene mandato a spigolare (giustamente), il "padrone" di Cosmos dice che GPL "puzza" e se ne esce con questo readme... direi appropriato no?

https://github.com/CosmosOS/Cosmos/blob/f0a54ed80b1a29abf75cbd5b22071c5be588884a/Build/Tools/cygwin/GPL%20Readme.txt


In bocca al lupo per il progetto.

In bocca al lupo anche a te!

fano
01-07-2017, 21:26
Eh, è una libreria attualmente attivamente usata per la ricerca. Devo terminare alcune cose e scrivere un articolo col mio prof per proporlo per una conferenza internazionale.
Con le pthread devo ammettere che mi sto trovando malissimo, ma forse sono io, buh.


No, non è un problema tuo come molto cose in Linux sono fatte con la filosofia "Worse is better": https://en.wikipedia.org/wiki/Worse_is_better


Il problema grosso è che sono partito da un programma già scritto malissimo, singlethreaded. Quindi immagina. Ho dovuto deallocare tutte le risorse che i geniacci facevano allocare, e tutto il resto.

Io mi trovo bene con C e riga di comando, anche se il progetto è grosso. Quello che non digerisco sono le cose scritte a cazzo di cane.


Il problema è che scrivere codice non "a cazzo di cane" in C è davvero difficile è il linguaggio che quasi ti obbliga a farlo mancando completamente di struttura (eh gli oggetti che se ne dica aiutano a "pensare" le cose in maniera diversa), il fatto che manchino tipi fondamentale (tipo le stringhe, le liste, i dizionari) e quindi ognuno se le re-implementa tutte le volte, la stessa gestione degli errore "sporca" il codice, ma d'altro canto se non la fai poi rischi che vada tutto in core appena ti giri dall'altra parte :eek:

Io ci provo scrivo il codice migliore che il C si sia mai meritato, poi lo do in mano ai miei colleghi torno tra un anno (il mio ruolo è un po' di "apri pista" diciamo creo cose nuove, ma solitamente poi non mi occupo della manutenzione) e non capisco più il mio codice... certo è devastato :cry:


Appena finisco mi studio CosmOS e .NET in maniera approfondita. :D

Sent from my HUAWEI VNS-L31 using Tapatalk

Ottimo! Se hai bisogno di "pointers" sono qui a disposizione :D

GTKM
01-07-2017, 22:46
No, non è un problema tuo come molto cose in Linux sono fatte con la filosofia "Worse is better": https://en.wikipedia.org/wiki/Worse_is_better



Il problema è che scrivere codice non "a cazzo di cane" in C è davvero difficile è il linguaggio che quasi ti obbliga a farlo mancando completamente di struttura (eh gli oggetti che se ne dica aiutano a "pensare" le cose in maniera diversa), il fatto che manchino tipi fondamentale (tipo le stringhe, le liste, i dizionari) e quindi ognuno se le re-implementa tutte le volte, la stessa gestione degli errore "sporca" il codice, ma d'altro canto se non la fai poi rischi che vada tutto in core appena ti giri dall'altra parte :eek:

Io ci provo scrivo il codice migliore che il C si sia mai meritato, poi lo do in mano ai miei colleghi torno tra un anno (il mio ruolo è un po' di "apri pista" diciamo creo cose nuove, ma solitamente poi non mi occupo della manutenzione) e non capisco più il mio codice... certo è devastato :cry:



Ottimo! Se hai bisogno di "pointers" sono qui a disposizione :D
Sicuramente ti sfrutteró :D

Sent from my HUAWEI VNS-L31 using Tapatalk

cdimauro
03-07-2017, 06:25
Anch'io in questo periodo sono molto preso con il lavoro! Spero un giorno tu abbia di nuovo tempo per il forum.

Posso aggiungere un nuovo capitolo solo per te:

The incredible stench of GPL

Un ragazzetto proprio uno o 2 giorni dopo che ho postato il qui se ne esce di aver trovato della "bratta" GPL dentro i sorgenti di Cosmos e che eravamo in qualche sorta di "violazione"!
Pretende pure che noi si aggiunga la frasetta del GPL al nostro progetto:

https://github.com/CosmosOS/Cosmos/pull/679/files

per fortuna usiamo solo degli exe e quindi il ragazzetto viene mandato a spigolare (giustamente), il "padrone" di Cosmos dice che GPL "puzza" e se ne esce con questo readme... direi appropriato no?

https://github.com/CosmosOS/Cosmos/blob/f0a54ed80b1a29abf75cbd5b22071c5be588884a/Build/Tools/cygwin/GPL%20Readme.txt

In bocca al lupo anche a te!
Grazie. :)

Il lattante lasciatelo perdere, perché non sa quello che dice. E' talmente immerso & perso nella follia ideologia del software diversamente libero, che non ne comprende i reali termini nonché limiti.

Il "capo" ha perfettamente ragione.

E ora, di corsa a lavoro.

Buona giornata!

fano
14-10-2018, 14:21
Come sempre un'immagine vale più di mille parole così... cosa sta succedendo dentro questa VM?

https://i.postimg.cc/1t12C51T/Cosmos-Zork.png

Dopo anni finalmente Cosmos è così maturo da poter emulare Zork :D

Questo è il changelog dell'ultimo UserKit rilasciato alcuni giorni fa:

This release includes the following:

* Net core 2 support
* New project system (No more Boot project needed!)
* More FAT/IO features implemented
* CGS works on VMWare
* More BCL plugs (Comparers, etc)
* Memory allocation performance improvements
* Zork demo

L'ultimo user kit lo trovate qui: https://github.com/CosmosOS/Cosmos/releases

Molte classi C# che richiedevano plugs sono state de-pluggate principalmente per 2 motivi:

1. IL2CPU supporta molte più feautere e non è più necessario "bypassarle" con i plug
2. Microsoft stessa sembra molto più confidente che C# può - effettivamente - essere scritto in C# e molte classi ora sono tutte codice managed (un po' va anche ringraziato Linux e la sua sprintf() che era 7x più lenta della controparte Windows e che ha convinto MS a fare tutto il codice di stampa / parsing di numeri in C#)

Ora ci concentreremo su far compilare Cosmos usando Net Core 2.1 perché ha ancora più classi managed e perché ha Span / Unsafe che per il nostro così low level sono molto comode.