Newsgroup: it.comp.os.dibattiti
Titolo: Eseguibili e bypassing del sistema operativo

Salve a tutti,
in questo periodo della mia vita mi sto appassionando ai sistemi operativi.
Voglio riprendere in mano le nozioni apprese al corso di SO1 e
approfondirle. Per questi motivi, credo che ogni tanto vi disturberò con
qualche messaggio nel caso di qualche dubbio.
(1)==========================================================
Il primo è il seguente e riguarda i file eseguibili.
E' noto che un programma direttamente eseguibile dalla CPU è uguale su tutte
le architetture di CPU della stessa famiglia. Poiché, tuttavia, il file che
contiene l'eseguibile ha un formato che varia da un sistema operativo
all'altro, abbiamo un problema di portabilità. Tuttavia, il resto del file
(il codice eseguibile) dovrebbe, come detto prima, mantenersi uguale per
tutte le architetture hardware. Questo accade perché se il file eseguibile
in questione esiste già vuol dire che è già stato compilato per un certo
processore e che quindi le chiamate di sistema specifiche per quel certo SO
sono già sate risolte con istruzioni macchina.
Alla luce di tutto questo, mi chiedo: non è possibile costruire un programma
convertitore che prenda in ingresso un file eseguibile nel formato di un
sistema operativo A e lo converta in un formato di un altro sistema
operativo B? Magari già esistono, ma io non ne sono a conoscenza.
(2)==========================================================
Poi ci sarebbe un'altra curiosità. Nell'organizzazione generale a livelli di
un generico sistema di calcolo descritto da Tanembaum il livello del
linguaggio assemblatore è posto sopra il livello di sistema operativo (che a
sua volta è posto sopra il livello ISA).
L'assemblatore è un programma il cui file eseguibile deve quindi essere
compatibile con il sistema operativo sottostante. Tanto per fare qualche
esempio, a parità di architettura hardware, e a parità di programma
assemblatore, deve esisterne una versione per Linux, una per Windows, una
per Solaris ecc...
Ora, è ovvio che non bisogna passare necessariamente per il sistema
operativo per eseguire programmi, altrimenti il primo sistema operativo
della storia non averbbe mai avuto origine (non esisteva infatti allora un
altro sistema operativo!).
Tuttavia, non mi sognerei mai di scrivere un sistema operativo in linguaggio
macchina o in ISA. Ricorrerei ad un linguaggio assemblatore o a C.
La domanda è: come faccio a scrivere sistemi operativi (o in generale
programmi) con linguaggi ad alto livello senza passare necessariamente per
un certo sistema operativo ovvero senza usare compilatori specifici per
Linux, Windows o altro?
Ciò che mi servirebbe è rebootare una macchina "vuota" (senza SO) e avviare
un editor o un ambiente minimale ibrido che mi permetta di compilare
qualunque sorgente per la piattaforma hardware utilizzata.
Come si fa?
Grazie per il tempo speso!
Fabio
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/


Non si fa. Creati il tuo os su Windows o Linux, e poi
fallo bootare all'avvio.
Ricordati: il fatto che si scriva un OS con strumenti
di Win, e che lo si compili con Win, **non** significa
che esso per funzionare abbia bisogno di Win.
Saluti
Pegasus

che esso per funzionare abbia bisogno di Win.
Lo ricorderò. Però ho un dubbio atroce. Se io scrivo il programma seguente
in C:
#include <iostream.h>
int main()
{
 std::cout<<"Ciao";
}
e lo compilo prima per Linux (ad esempio con gcc), poi per Win32 (ad esempio
con Borland C 5.5) e infine per DOS 6.22 (ad esempio con Borland Turbo C++
3.0), i tre file compilati, non dovrebbero avere le loro più significative
differenze nei loro header?
Inoltre, proprio per il fatto che queste differenze di "formato"
identificano un particolare sistema operativo, come faccio a dire alla
macchina, durante il boot, di ignorare la parte che "non le interessa" e
farle prendere solo il codice macchina?
Ciao.


 farle prendere solo il codice macchina?
La cosa è un pochino più complessa di come la vedi tu.
Ora ti spiego. Intanto devi creare un boot loader che lavori
"on a bare machine", cioè che lavori prima che venga caricato
un qualsiasi sistema operativo.
Qui bisogna conoscere i dettagli della programmazione assembler
su PC x86 e tutta una serie di informazioni relative agli
interrupt ed alla architettura x86.
Ci sono due libri di testo che io reputo ottimi:
a) La bibbia del programmatore x86
b) Il linguaggio assembler
entrambi di Peter Norton. Se vuoi posso guardare la casa editrice:
sono molto vecchi, ma ci sono esattamente le informazioni che ti
servono. In particolare, vengono spiegati in dettaglio il
funzionamento degli interrupt del BIOS ed il processo di boot.
Ricordati che in fase di boot, il tuo programma boot loader
può richiamare solo ed esclusivamente interrupt del BIOS (puoi
accedere solo da lì). Ora, tu devi scrivere un boot loader.
Si può fare in assembler, usando MASM, LINK, EXE2COM, ma il
problema è che ottieni un file .COM che ha gli header del DOS
(che tu non vuoi), pertanto dovresti fornire al compilatore
MASM delle direttive per fare in modo che i primi byte
dell'immagine del boot loader siano eseguibili.
Per tale motivo, in genere si sceglie una strada leggermente
differente. In sostanza, si parte dal vecchio programma
debug di Ms-Dos, e si scrive il codice del boot loader
in raw assembler. Poi, si dice a debug di salvare il codice
macchina che abbiamo scritto in un file di 512 byte (la
dimensione di un settore).
Infine, si scrive un programma in C per copiare questo
file di 512 byte nel settore 0000 del disco (di solito
tutto questo si fa in un disco virtuale creato con
Vmware o Bochs, perchè se si facesse sul tuo vero
sistema e sul tuo vero disco fisso, il tuo vero boot
loader verrebbe sovrascritto e non partirebbe più
il PC).
Fin qui ci siamo? Quindi, adesso abbiamo un disco
virtuale VMware totalmente vuoto, salvo che al settore
0000 dove abbiamo copiato il codice macchina del
nostro boot loader. Poichè all'avvio il sistema
carica automaticamente il settore 0000 del primo
disco fisso del sistema (almeno se così il BIOS
dice), questo significa che la prima cosa che il
processore eseguirà all'avvio sarà il tuo boot loader.
A cosa ti serve il boot loader? A prendere il controllo
della macchina. In sostanza, in quei 512 byte di codice
devi fare questo:
a) individui l'immagine del kernel del tuo sistema
operativo sul disco (la sai perchè la posizione la
decidi tu, poi ti spiego come)
b) porti l'immagine del kernel in memoria (nel primo
Mb, perchè finchè sei a 16 bit puoi accedere con
facilità solo a quella);
c) inserisci nel tuo codice un bel JMP 0000:[Entry point
nell'immagine del kernel]
In questo modo il boot loader passerà il controllo all'
immagine del kernel nello spazio di 1 Mb. E' chiaro che
poi è questa immagine che deve fare il resto (ad
esempio, commutare a 32 bit in modo da accedere a tutta
la memoria ed iniziare il processo di boot).
Come crei l'immagine del kernel? Per farlo ti serve
sostanzialmente un ambiente di sviluppo (DevCPP + GCC
vanno benissimo), ed un set di librerie che assicurino
dei servizi appoggiandosi solo al BIOS (no, stdio.h
non va bene). Per esempio, le librerie di oskit.
Non lanciarti subito nella stesura del kernel, perchè
è una cosa molto, molto complessa. Prima studiatevi i
sorgenti di Linux e FreeBSD, che sono quanto di meglio
possiate trovare.
E' chiaro che, una volta creata l'immagine del kernel,
il tuo unico problema è capire dove si trova l'entry
point del codice, ed impostare il boot loader di
conseguenza.
Ricordati infine che il boot manager non ha alcun codice
per accedere ad un file system, pertanto, devi crearti
un utility che copi in un punto preciso del disco
l'immagine del kernel e la devi usare dopo ogni
compilazione (Mi raccomando, su un disco virtuale
VMWARE!!!!).
Saluti
Pegasus

 Come si fa?
Ti procuri un cazzutissimo libro sugli ibm compatibili, scrivi il boot 
loader in assembly, scrivi tutte le routine e ti fai un bel culo.
Se vuoi, scarica il kernel NewOS, di uno degli autori di BeOS, è un mega 
e basta di codice, veloce, microkernel. Studialo e buona fortuna!

 assembler, ma a che serve?
l'hanno già fatto.
http://www.menuetos.net/

 Non puoi. E non ha senso farlo.
Nient'affatto. O meglio, non e' del tutto vero. Mai sentito parlare
di "cross compiling"?
bye G.L.
p.s.: non ti rispondo perche' ti ho in KF: questo post e'
stato scaricato prima del filtraggio.

 stato scaricato prima del filtraggio.
Ed anche perchè non sai cosa rispondere (vedi mancata
risposta sul post della compatibilità binaria).
Pegasus

 sono già sate risolte con istruzioni macchina.
falso. pensa per esempio che non tutti i sistemi operativi chiamano le
syscall allo stesso modo.
Il massimo che puoi avere sono librerie o spezzoni di codice compilato
come position independent code che non necessitino di nessuna altra
funzione esterna. Il che e' un po' come funzionano alcuni codec video.

Ragazzi, vi ringrazio tutti per i vari interventi.
Benchè abbia visto pareri un pò contrastanti ho grossomodo compreso il
problema.
Tuttavia vorrei ripetere le mie domande in modo più conciso e migliore da un
punto di vista espressivo, perché ho capito che qualcuno non ha compreso
bene qualche mio dubbio o qualcosa che ho detto.
Mi spiego dunque meglio.
(1)
Per quanto riguarda il primo dubbio:
quando dicevo che due codici macchina (per una stessa macchina) compilati da
due compilatori su due sistemi diversi sono uguali intendevo dal punto di
vista computazionale, non sintattico. Entrambi i codici sono dunque pronti
per essere eseguiti dal microprogramma scritto in Mic che provvederà a
tradurre per la CPU.
La vera differenza (quella non computazionale) sta nell'header, che cambia
da sistema a sistema.
Per cui, almeno in linea teorica, dovrebbe essere possibile, e di fatto lo
è, per quanto complcato, costruire un programma traduttore che traduca un
codice eseguibile finale per un sistema in una altro codice eseguibile
finale per un altro sistema.
(2)
Il secondo dubbio va formulato diversamente.
Il dilemma è: dato un codice eseguibile finale compilato con un certo
sistema operativo, come faccio a farlo eseguire direttamente al
microprogramma, senza passare per il sistema operativo?
Infatti, il compito del sistema operativo è dare in pasto al microprogramma
la parte del file che corrisponde al codice ISA. Questo, lui lo sa fare
perché conosce la struttura dei suoi file. Il SO sa in che posizione del
file inizia il codice ISA.
La domanda è: se io ho un file compilato, ad esempio, per Windows, è
sufficiente, conoscendo la struttura dei file di Windows, dare in pasto al
microprogramma il codice che comincia al giusto offset per averne
l'esecuzione? Naturalmente sto parlando di programmi che non utilizzano
binding dinamico, cioè di programmi che hanno in tasca tutto ciò che devono
fare, senza ricorrere a system calls o librerie dinamiche.
Inoltre, sappiamo che il livello del linguaggio Assemblatore è situato
appena sopra il livello del Sistema Operativo. Ora, mettiamo che io voglia
scrivere un programma in Assembly senza ricorrere ad un assemblatore per un
certo sistema operativo (e quindi senza fare chiamate di sistema, al massimo
quelle del BIOS), o, più in generale, che voglia scrivere un programma in
linguaggio L senza ricorrere ad un compilatore per L specifico per un dato
sistema: dovrei disporre di un Assemblatore (o, più in generale, di un
compilatore) che compili direttamente per il microprogramma.
La domanda è: questi tipi di programmi esistono già? E in ogni caso,
conviene utilizzarli o programmare direttamente su un qualunque sistema
operativo convenendo di dare poi in pasto al microprogramma soltanto le
parti dei file prodotti che corrispondono al codice ISA?
(3)
Una domanda finale.
Mettiamo che io abbia compilato il programmino ciao.c in Borland C++ 3.0.
Rimandando i dettagli ad una lettura personale dietro vostro consiglio
(qualcuno me ne ha già dati), vorrei sapere in modo grossolano:
1 - Come faccio a estrarre il codice ISA da ciao.exe?
2 - So che, all'accensione, è il BIOS che va a leggere il codice contenuto
nel MBR e lo passa al microprogramma. Come faccio a "mettere" sul MBR il
codice estratto da ciao.exe, in modo che il BIOS lo legga?
Ciao a tutti e grazie.


 bene qualche mio dubbio o qualcosa che ho detto.
Non te ne avere a male, ma IMHO hai le idee parecchio confuse. Ti
converrebbe riprendere in mano i libri di testo. E conta molto
la pratica, per comprendere di cosa si sta parlando: da parte mia, e'
iniziata programmando in esadecimale su z80 su una macchina priva di
sistema operativo (ma solo un monitor residente su rom). Poi "sotto"
un sistema operativo: macro assembler pdp11 su rsx11-m+, osservando
i listings e le espansioni delle macro per osservare le chiamate di
sistema e la relativa preparazione che precede l'istruzione svc.
io ti darei dei suggerimenti:
1) Cosa intendi per microprogramma?
   1a) Non e' il sistema operativo.
   1b) Il sistema operativo non e' un interprete.
   1c) In questo discorso si puo' trascurare il fatto che la cpu sia o
       meno microprogrammata, dato che il microprogramma e' ben altra
       cosa da quello che sembra tu pensi.
   1d) Non e' il processore che riconosce l'header ma il sistema 
       operativo. Il formato del binario e' legato al/ai sistema/i
       operativo/i che lo deve/devono eseguire.
2) Si deve per forza distinguere fra un programma eseguito con o senza
    sistema operativo.
    2a) Nel primo caso, per potere effettuare I/O, il programma ha
        imprendiscibilmente bisogno di effettuare delle syscall al
        sistema operativo, syscall specifiche del sis. op.
    2b) Non conta il fatto che il programma possa essere linkato
        staticamente o dinamicamente alle librerie: puo' essere
        anche un "monolite", ma in qualche punto il processo deve per
        forza effettuare una syscall per fare I/O attraverso il sis.
        op., che e' semplificando un'interfaccia (invalicabile) fra il
        programma e l'hardware.
    2c) Un programma fatto per essere eseguito "on a bare machine"
        (cioe', su una macchina che non esegue un sistema operativo)
        difficilmente puo' girare sulla macchina col sistema operat.,
        e viceversa un programma fatto per un particolare sis. op.
        difficilmente puo' girare "on a bare machine".
bye G.L.

 codice estratto da ciao.exe, in modo che il BIOS lo legga?
INT 13h: Write sector to disk.

 C'è. Basta che vedi Wine. Ma ricorda, non basta l'header.
Potremmo considerare della stessa "specie" anche Rosetta?
(in realtà lì il sistema è sostanzialmente lo stesso, cambia però quello 
che c'è "sotto").
Ciao

 
Si, e Rosetta è ben più complesso, dovendo tener conto delle diverse 
architetture. Diversi opcode, diverse lunghezze, diverse convenzioni di 
endianness. Un macello.
Me ne ero completamente scordato.

 Me ne ero completamente scordato.
In realtà (magari mi sbaglio) credo che Fabio intendesse qualcosa di 
diverso, una sorta di traduttore che da un eseguibile Win (per esempio) 
tirasse fuori un eseguibile Linux o un eseguibile MacOS o un eseguibile 
GalaxyOS :)
ciao ciao

Mamma mia che confusione totale. Facciamo un pò di ordine.
Noto che avete molte e dettagliate conoscenze tecniche. Ragion 
per cui, mi rivolgerò a voi in futuro in caso di necessità di 
informazioni.
Noto però che c'è qualche piccolo problema di compatibilità di 
linguaggio per cui non ci comprendiamo abbastanza.
Partiamo dall'organizzazione generale a livelli di un moderno 
sistema di calcolo proposta da A. Tanembaum. Ecco come si 
presenta:
----------------------
| C, C++, Java, ...  | Ln con n>5
----------------------
          |          
         ...
          |
----------------------
| Assembly           | L5
----------------------
          |
----------------------
| Sistema Operativo  | L4
----------------------
          |
----------------------
| ISA:               |
| Instruction        |
| Set                |
| Architecture       | L3
----------------------
          |
----------------------
| Microprogramma     | L2
----------------------
          |
----------------------
| Microarchitettura  | L1
----------------------
          |
----------------------
| Logica digitale    | L0
----------------------
          |
----------------------
| Dispositivi elettr.| L-1
----------------------
          |
----------------------
| Fisica dei semicon.| L-2
----------------------
Il livello interessante per i programmatori di sistema sono 
quelli compresi tra L0 e L5. I livelli sottostanti riguardano 
gli ingegneri elettronici e informatici.
I restanti livelli superiori sono di competenza dei 
programmatori di applicazioni.
Il livello microarchitetturale è composto dal datapath (ALU, 
unità di controllo, bus, registri...). L'unità di controllo 
gestisce il ciclo di fetch-decode-execute. Tale funzionamento è 
controllato da un programma detto microprogramma scritto 
nel "vero" linguaggio macchina, il Mic. Questo programma legge 
le istruzioni del livello immediatamente superiore, il livello 
ISA, che è un set di istruzioni leggermente meno semplici di 
quelle del Mic. Questa suddivisione permette ai progettisti di 
CPU di realizzare microprocessori semplici dal punto di vista 
dell'architettura e del linguaggio accettato, deputando 
l'interpretazione di istruzioni più complesse a questo benedetto 
microprogramma, scritto in Mic (il linguaggio riconosciuto dalla 
CPU).
Le case costruttrici di computer, nei manuali tecnici, riportano 
le istruzioni ISA come fossero le istruzioni macchina, ma in 
realtà non è così, la CPU non sa eseguire direttamente le ISA.
L'Assembly è un linguaggio mnemonico per le istruzioni ISA e 
contiene anche le istruzioni mnemoniche per effettuare le 
chiamate di sistema.
Il sistema è un livello ibrido che contiene istruzioni ISA e in 
più aggiunge nuove funzionalità (le chiamate di sistema).
Come potete vedere, io non ho le idee confuse.
Adesso è tutto chiaro?
Fabio
--  
Postato da Virgilio Newsgroup: scopri i nuovi gruppi 
Eros, foto e video a 
http://newsgroup.eros.virgilio.it

 Come potete vedere, io non ho le idee confuse. Adesso è tutto chiaro?
Eh si', ma ora che hai evidenziato che "ne sai", quali sarebbero i
dubbi, che tra l'altro, alla luce delle tue precisazioni, NON hai
reiterato nel presente post? Qui non si fa gara a chi ne sa di piu',
al limite si cerca di scambiare opinioni e informazioni per arricchirci
vicendevolmente....
p.s.: quota i messaggi.
bye G.L.

 ha scritto nel messaggio 
news:RD3bf.24031$65.7...@twister1.libero.it...

Assolutamente no.
WINE non è un vero e proprio emulatore (ed infatti
Wine sta per "Wine is not emulator").
L'idea di Wine è la seguente: partiamo dal presupposto
che il formato degli eseguibili Windows è noto (non
fosse altro perchè è lo stesso degli .EXE del Dos),
ed intanto facciamo sì che il nostro programma
faccia girare questi .exe in ambiente linux (questo
si fa attraverso un processo linux che emula il
comportamento del kernel di windows, e che
ospita i vari .exe che vengono "emulati" da wine).
Nota che l'exe di windows gira sotto linux. Ogni
volta che tale exe cerca di richiamare una dll,
interviene wine che fa da wrapper, traducendo la
chiamata in una chiamata compatibile con le
librerie di linux. In altre parole, il processo di
traduzione non riguarda il codice, ma solo le
syscall e le librerie di sistema (e solo quelle di
sistema, le dll che sono ad un livello superiore e
si appoggiano su librerie di sistema sono gestite
così come sono, vedi Lindows dove puoi
installare office da setup.exe senza problemi).
Al contrario, per Rosetta è *totalmente* differente.
Lì si tratta di trasformare codice PowerPC in codice
x86. Ma questo in teoria non sarebbe possibile
perchè le istruzioni sono totalmente diverse (PowerPC
usa istruzioni RISC tutte della stessa lunghezza e
big endian, mentre x86 usa istruzioni CISC a 16/32/64 bit
con vari modalità di indirizzamento ibride, memorizzazione
dei dati numerici di tipo little endian, un numero di registri
molto inferiore, ogni istruzione può occupare da 1 a 6 byte
e via dicendo....).
Allora come si fa?
Quando ci si trova di fronte a questo problema, ci sono
due possibilità:
a) crei un microprocessore emulato via software. E' la strada
scelta degli emulatori C64 o SNES. Permette di emulare
perfettamente una piattaforma che ha un processore diverso
dal tuo (ed hardware diverso dal tuo), ma purtroppo è
spaventosamente lenta;
b) ricompilazione dinamica. L'eseguibile viene letto come se
fosse un linguaggio di programmazione, ed un processo trasforma
le sue istruzioni passo per passo in un nuovo programma
costituito da codice x86 compatibile, che viene dato in
pasto al vero processore x86 del PC. E' la strada seguita
dagli emulatori PSX, PSX2, N64, GameCube. E' molto
veloce, ma purtroppo non garantisce **mai** la
compatibilità del binario (in pratica, occorre fare delle prove
per ogni binario e vedere se va, ma non si possono dare
garanzie in generale).
La b) è anche la strada di Rosetta.
Saluti
Pegasus


Aspetta, aspetta....
Stai confondendo completamente gli ambiti.
Ascoltami, posso darti un consiglio? Comprati un libro di
testo che si chiama Bucci, Architetture dei calcolatori
elettronici. E' un testo specializzato per noi ingegneri elettronici,
ma serve anche a voi informatici: ti chiarirà le idee. Le cose
non stanno come le stai vedendo tu.
O meglio, puoi vederle anche in quel modo, ma non ti portano
da nessuna parte per progettare un sistema operativo.
Dunque, facciamo qualche osservazione.
In primo luogo, tu devi vedere il processore semplicemente
come un sistema che ha dei registri interni, e che ha delle
istruzioni. Punto.
L'implementazione di queste istruzioni a te non interessa dal
punto di vista del sistema operativo. Per esempio, devi
sapere che le cpu Intel ed Amd traducono le medesime
istruzioni x86 in diversi microcodici ("Diversi" addirittura
da modello a modello della stessa casa produttrice, so
che può sembrarti pazzesco, ma non lo è), ma tu non te
ne accorgerai **mai**.
In altre parole, UNREAL.EXE gira allo stesso modo sia
su un Athlon64 che su un Pentium III, **anche se**
l'istruzione MOV EAX, 7362 (assembler a 32 bit),
viene tradotta in modo diverso dall'unità di traslation
interna al microprocessore.
Per quanto ti riguarda, tu lavori su una famiglia di
processore che segue un certo standard ISA, e che
quindi riconosce un certo set di istruzioni. Il resto
lascialo agli ingegneri elettronici (anche perchè non
hai modo di accederci a livello di linguaggio, quindi
non lo vedrai mai dal punto di vista dell'os).
Poi c'è un secondo problema: vedi che un sistema
operativo ****NON**** è un insieme di syscall.
Saluti
Pegasus

 cambio di architettura.
Credo tu abbia ragione, in effetti io il passaggio a intel l'ho visto 
subito come possibile visto che coreimage funzionava (e funziona, è 
impressionante).
Per altivec non ti so dire, possono essere molto ma molto ma molto bravi 
e spostare su SSE.

 
...e spero tu non abbia rovinato un NDA :)

 Adesso è tutto chiaro?
Un po' confuse si, le hai. Mischi ciò che è nella macchina a livello 
programmabile, da ciò che non lo è.
Tanto per farti comprendere prendi il DOS. Le syscall erano messe con 
software interrupt, INT #. Quando il processore vedeva INT 21h quello 
che faceva (pensa ad int come una macro) era PUSHA, poi un bel CALL FAR 
[21h * 8] (l'interrupt vector table era in 0000:0000), svolgeva quello 
che doveva fare, per esempio la funzione 9 (in AH) per scrivere su 
schermo poteva o usare IN ed OUT oppure scrivere direttamente a memoria 
video (A000:000), alla fine un bel IRET che faceva un POPA.
Mo sotto di questo, ovvero vedere MOV AH, 9 cosa fa DENTRO al 
processore, non lo puoi fare. Sai l'effetto, e basta. Sotto ci vai se 
sei un ingegnere elettronico.

 ...e spero tu non abbia rovinato un NDA :)
Non dovrei.....
Saluti
Pegasus

 delle console)
VMWare non emula il comportamento di un PC?
Un OS *pensa* di avere sotto di se un intel-compatibile con bios, scheda 
video, audio, cd... emula questo comportamente passando le richieste hw 
all'hw vero quando necessario. Per l'OS ospitato quindi è un emulatore.


Sì, ma il mio "assolutamente no" si riferiva al contesto del
discorso. Spiego meglio.
VMWare è un multiplexer software. I processi del sistema
operativo ospitato vengono eseguiti dalla vera cpu x86
che esegue i processi del sistema ospitante.
Quindi, l'unica cosa che fa VMWare è intercettare le
istruzioni OUT ed IN del processore, così come gli
interrupt, ed avviare le routine di emulazione dell'hardware.
La differenza è che mentre in un emulatore SNES o C64
il processore è emulato via software (e quindi tu hai del
codice ASMx86 che legge un
98 23 00
lo traduce in LDA 0023, e richiama una routine
Procedure EmulateLDA (Address:word);
Begin
  VirtualRegistry.A=Memory [Address];
End;
in un ambiente VMWare il microprocessore del sistema
ospitato **non** viene emulato via software (ed è la
ragione della velocità di Vmware).
Siamo d'accordo che è un emulatore, ma non fa parte della
classe di emulatori che emulano il processore.
Saluti
Pegasus

 e spostare su SSE.
Ah beh... in futuro (quando uscirà il primi Macintel ufficiale) potrebbe 
anche essere, ma per ora non è così, e mi pare non siano nemmeno 
previsti ulteriori sviluppi in tal senso. Dopotutto Rosetta dovrebbe 
servire solo per un breve periodo: molti sw sono già Fat Binaries, 
quelli di Apple sono già pronti, e anche Adobe per la fine del prossimo 
anno (con qualche mese di ritardo) dovrebbe rilasciare versioni per 
MacOSX-x86. Non credo che Apple voglia investirci più di tanto: ha fatto 
un ottimo lavoro che funziona a dovere, ma non credo che andrà oltre.
ciao

 
Anche secondo me, visto che ha brevettato un sistema di traduzione da OS 
diversi e architetture diversi, con espliciti "Windows", "MacOSX" e "Linux".
Cosa ha in serbo Jobs però non si sa...

 all'hw vero quando necessario. Per l'OS ospitato quindi è un emulatore.
Per il poco che ne so:
Vero che le periferiche vengono emulate, ma col supporto per le VM su
linux e windows >=2k, il codice a ring3 mi sa che viene direttamente
eseguito. Cio' che viene sottoposto a emulazione e' il codice a ring0.
Se anche il processore venisse emulato (vedi bochs), allora si
parlerebbe di emulazione, non di macchina virtuale.
bye G.L.

 mathematica, femlab... altri schemetti mi basta omnigraffle :) Niente 2D.
...fatto anch'io in passato, ma ora faccio tutt'altro.
Ciao

 codice estratto da ciao.exe, in modo che il BIOS lo legga?
devi fare in modo che all'inizio del file ci sia la struttura prevista
dallo standard multiboot e poi con lilo, grub o quant'altro lo carichi e
lo fai partire. Nella documentazione di grub trovi lo standard, il
codice gia' implementato e' nell'oskit.

 ----------------------
ehm... questo secondo me non e' molto corretto. Perche' lo stesos
sistema operativo si basa sull'assembly.

 Fabio wrote:


Ottima osservazione, che mi ha fatto pensare a 'sto punto una cosa:
per me, fra i suoi diversi dubbi, il suo principale equivoco sta
proprio qui: poiche' ha affermato (IMHO correttamente) che il
linguaggio assembly che la macchina presenta al di sopra del sistema
operativo e' assimilabile piu' o meno, per un verso ad un'estensione
del "linguaggio naturale" e delle capacita' della macchina hardware
(e dall'altro di converso ad una limitazione posta per motivi di
virtualizzazione, isolamento e protezione), IMHO sta confondendo il
microprogramma / microcodice (ovvero la logica interna cablata e/o
microprogrammata della cpu) con il "linguaggio naturale" assembly del
processore, e l'assembly col linguaggio macchina proprio della "macchina
virtuale" (non in senso VM by IBM, intendiamoci...) generata dal sistema
operativo. Apposta IMHO pone l'assembly al di sopra del sistema
operativo.
bye G.L.

Uff...perché non riesco a farmi capire? :-(
Intanto, a scanso di equivoci, devo dirvi che sono laureando in 
Informatica (quinquennale), quindi non pensate a me come ad un 
profano. Il problema è che la materia "Architetture degli 
elaboratori" e "Sistemi operativi 1" sono state le prime materie 
che ho dato, quando capivo ancora poco di Informatica (benché 
fossi un perito informatico).
Dopo 5 anni, riprendendo in mano i libri mi sono reso conto che 
all'epoca, quando ne diedi gli esami, non ero pienamente 
cosciente delle nozioni apprese.
Oggi voglio imparare molto di più sul sistema "elaboratore" a 
livello della macchina, e non solo da un punto di vista teorico. 
Questo per due motivi:
 1 - Sapere davvero come funziona la macchina
 2 - Sapere davvero come funziona un sistema operativo
Essendo un Informatico, so che devo partire dallo studio delle 
architetture dei computer. Questo è quello che sto facendo 
autonomamente sui libri.
Ecco i perché di questo post sul bypassing del sistema operativo.
Mi rendo conto che il discorso è degenerato da parte mia 
nell'intento di mettermi d'accordo con voi su terminologia e 
roba varia.
Rifaccio ordine e suddivido gli "accordi termilogici e 
concettuali" dalle "specifiche dei miei problemi". Ok?
---------
 ACCORDI
---------
 1. Chi non è d'accordo con me sulla suddivisione a livelli di 
un moderno sistema di calcolo dia una occhiata al "Architetture 
dei calcolatori, A. Tanembaum - Prentice-Hall".
 2. E' vero che non tutte le CPU sono microprogrammate. Ho 
sbagliato se ho fatto erroneamente capire il contrare.
 3. Non voglio scendere in accorgimenti prettamente tecnici. 
Parlando quindi solo di teoria, penso che si possa dire che 
l'ultimo livello visibile ad un programmatore di sistema sia il 
livello ISA, con il quale può interagire SOLO attraverso un 
assemblatore. Ok?
 4. Il sistema operativo, detto in soldoni, è una interfaccia 
tra utente e macchina. Esso fornisce, in quanto macchina 
(astratta) esso stesso:
 
    a. Algoritmi e strutture di dati per la gestione delle 
risorse (memorie, file system, paginazione, scheduling, 
dispositivi ecc...);
    b. Un linguaggio interno, estensione del livello ISA;
Il fatto che sia scritto in Assembly (o C o C++) non lo pone 
sopra tali livelli. Sistema operativo SOTTO Assembly vuol dire 
che, quando programmiamo in Assembly *POSSIAMO* sfruttare anche 
le istruzioni del sistema operativo. Il linguaggio del sistema 
operativo è invece costituito dal set ISA più le system-calls: 
non vi è traccia di Assembly, ma solo di sequenze di codici 
esadecimali.
L'introduzione del livello del linguaggio assemblatore è stata 
fatta *appunto* per semplificare il compito del programmatore di 
sistema, grazie al suo tipico linguaggio mnemonico. Tuattavia la 
corrispondenza con il linguaggio ISA (in pratica, il linguaggio 
macchina) è (ripeto, teoricamente, salvo ottimizzazioni) di 1 a 
1 ed altrettanto con il linguaggio fornito dal sistema operativo 
(sempre ottimizzazioni permettendo).
Quindi il livello del linguaggio assemblatore sta SOPRA il 
livello del sistema operativo.
Per costruire un sistema operativo è sufficiente scrivere codice 
Assembler ma utilizzando (ovviamente) solo le istruzioni pseudo-
ISA.
------------
 SPECIFICHE
------------
Bene bene bene...,
ora che (spero) tutto è chiaro, i miei problemi attuali sono i 
seguenti:
 1 - Come si scrive (come si compila) in generale un programmino 
che venga eseguito direttamente all'avvio del computer, subito 
dopo i controlli del BIOS?
[Questo mi serve per capire come fare un bootloader personale.]
 2 - Come faccio (in linea teorica) ad estrarre il codice 
eseguibile da un file di un programma eseguibile compilato su un 
generico sistema operativo?
[Questa è una curiosità che potrebbe essere utile in futuro.]
Fine.


 [Questa è una curiosità che potrebbe essere utile in futuro.]
A questo non so rispondere. Ma partendo dal sorgente, di sicuro puoi
ottenere il listato assembler anziche' un file oggetto all'atto
della compilazione. Nota che su molti sistemi i compilatori sono
organizzati secondo una gerarchia, con compilatori per linguaggi ad alto
livello che generano il listato in linguaggio C, il quale a sua volta
genera un listato in assembly: queast'ultimo ("as") poi generera' i file
oggetto che, tramite il linker (ultimo anello della catena,) daranno
luogo al file contenente l'eseguibile.
bye G.L.

 generico sistema operativo?
disassemblando. Ma non ti conviene leggere programmi opensource?

 (altrimenti, come si farebbe a produrre codice "di sistema"?).
ma c'e' un problema, non basta una normale compilazione. Devi dire
all'assemblatore che l'inizio del file ha una specifica organizzazione.
Comunque tra la documentazione e i sorgenti di grub e l'oskit trovi
teoria e tecnicna del multiboot.

 l'oskit trovi teoria e tecnicna del multiboot.
Thanks, vedro' di darci un'occhiata (sperando di capire qualcosa,
visto che ho fatto una settimana di fondamenti del C anni fa,
e basta...).  ;-)
bye G.L.


Scrive il suo codice in Assembler inserendo
la direttiva
.MODEL SMALL
in modo che tutto il codice sia contenuto in
un unico segmento da 64k (DS=CS).
Poi compila il codice assembler con MASM
(in modo da ottenere l'.OBJ), passa tutto al
linker per ottenere l'EXE.
Adesso da un bel
EXE2BIN MYPRG.EXE MYPRG.BIN
in modo da ottenere il suo codice in un binario
dove sia il codice che i dati stanno tutti nello
stesso segmento.
Adesso un bel:
DEBUG MYPRG.BIN
-u 0100
consente di ottenere il codice assembler raw. Con debug
poi si scrivono sul disco i byte di codice macchina che
interessano.
Saluti
Pegasus

esadecimali.
Ma proprio manco per niente. Un sistema operativo
non fornisce un linguaggio, nè tantomeno questo
può considerarsi un estensione del livello ISA.
Fa un bel
Debug Command.com
e te ne accorgi. Tu vedi assembler, solo assembler
(anzi, raw assembler cosa ben diversa dall'assembler
vero e proprio). Sai dove sono le chiamate alle funzioni
dell'OS?
Quando vedi qualcosa tipo:
MOV AH,02
INT 10
Ma questo è vero solo negli os interrupt based (come il dos),
mentre per esempio potrebbe non essere più vero negli os
multitask (dove le chiamate alle funzioni del sistema operativo
possono essere anche di tipo diverso da una INT, per esempio
un JMP o un CALL FAR ad un entry point noto, od una vera
e propria richiesta di IPC). Addirittura nel C64 c'era un os, ma
non esistendo l'istruzione INT si eseguiva un istruzione JSR.
In ogni caso, è l'assembler del processo che richiama altri
pezzi di assembler del sistema operativo, ma il sistema operativo
non estende l'assembler. Non lo fa. Punto.
Osserva poi che nella tua visione del problema, l'os è un insieme
di syscalls. Allora anche il BIOS è un OS.
Così non è, anche perchè ogni OS ha un meccanismo di gestione
degli eventi (anche il Dos c'è l'ha), ed in quel modello è totalmente
ignorato.
L'os **non** estende il linguaggio.
Saluti
Pegasus 

 Pegasus 
Ciao


 disassemblando.
Ach! E dire che l'ho fatto diverse volte in dos (sourcer).  :-)
BTW, IMHO Fabio voleva sapere come ottenere uno spezzone di
codice "puro" da far girare direttamente sull'hardware.
bye G.L.


No: il suo "linguaggio è esteso dall'os mediante le syscall"
è un concetto errato.
Hai anche scritto:
"Il linguaggio del sistema operativo è invece costituito dal
set ISA più le system-calls: non vi è traccia di Assembly,
ma solo di sequenze di codici esadecimali".
Ed è sbagliatissimo: non solo un os non ha un linguaggio
(semmai ha una API, che è cosa ben diversa), ma
soprattutto, sia il sistema operativo che i processi
utenti sono in assembler (o meglio ancora in C).
La frase "non vi è traccia di assembly" è errata. Ed è
un errore grave: vedi che il codice macchina (numeri)
e l'assembler raw (quello che si ottiene con Debug
o Codeview), **non** sono due livelli posti uno
sotto ed un sopra, ma sono due modi di leggere la
stessa informazione.
Io posso provare a disassemblare Command.com:
DEBUG 
COMMAND.COM
E vedere il codice come codice macchina:
d CS:0100
o vedere la stessa cosa come raw assembler
u 0100
Saluti
Pegasus

 linguaggio macchina.
ecco qua, come volevasi dimostrare. Secondo me tu introducendo questo
ISA hai deta luogo ad una ambiguita' cui nemeno tu sai sottrarti.
ciao

 operativo"?
n.b., non e' mia intenzione correggerti, perche' dal tuo punto di vista
(e dal punto di vista diversi testi sui sistemi operativi) e' corretto,
e si vede bene che hai fondamentalmente le idee abbastanza chiare. Ma e'
opportuno fare una precisazione, al fine di evitare fraintendimenti:
e' opportuno chiarire che, di per se, il sistema operativo non apporta
nessuna estenzione al livello ISA (o meglio, addirittura: in user space,
per svariati motivi, pone limitazioni a tale livello), piu' che altro le
chiamate a sistema possono essere viste astrattamente come istruzioni ad
"alto livello" aggiunte al linguaggio macchina del livello ISA, ed in
tal senso come una estensione del linguaggio "naturale" della macchina,
ma penso che Francesco Tisato possa esprimersi meglio di me (in corsivo
le mie considerazioni) in qualche estratto di "progetto di sistemi
operativi":
<paste>
2.2 _Riduzioni ed estensioni al set di istruzioni_
nel paragrafo precedente si e' visto come un SO possa generare macchine
virtali il cui insieme di istruzioni eseguibili coincide con quello
della macchina fisica ( /n.b.: si riferisce chiaramente a VM-370/ ,
/ paragrafo 2.1.4, ma il discorso e' poi affrontato in termini di /
/ "risorse virtuali" / ). In generale cio' non si verifica per due
motivi: in primo luogo, l'esigenza di riservare al SO il controllo di
alcune funzioni base produce una riduzione nel set di istruzioni
disponibile per i programmi d'utente; in secondo luogo, usualmente il
SO non si limita a funzionare da smistatore di richieste, ma e' in grado
di presentare all'utente una macchina piu' "gradevole", con un insieme
di istruzioni piu' potente, che esso traduce in istruzioni hardware.
2.2.1 _Istruzioni privilegiate_
[CUT]
2.2.2 _Introduzione di nuove istruzioni_
Si e' detto finora che le richieste di utilizzo di una risorsa virtuale
da parte di un programma si traducono in una istruzione di tipo SVC.
In pratica, chiamate al SO possono venire considerate come istruzioni
della macchina virtuale creata dal SO; e tali istruzioni sono,
usualmente, molto piu' potenti e facili da usare di quelle della
macchina fisica.
[CUT]
</paste>
bye G.L.