I comandi Linux: il sistema | OTHER chapters | ||||
La scheda madre è il cuore di un computer. La scheda madre, o motherboard, è un grande circuito stampato, in cui trovano posto chip, connettori ed altri apparati elettronici. Tutti i dati, in un computer, passano dalla scheda madre. In essa, trovano posto diversi componenti, tutti collegati l'uno all'altro: una motherboard ( scheda madre ) è, in realtà, composta da più strati: in cima, troviamo i componenti, mentre ciascuno degli strati sottostanti ospita una parte dei circuiti che collegano i vari componenti. I componenti di una scheda madre, ovviamente, variano da scheda madre a scheda madre, ma alcuni di essi sono presenti nella scheda madre di qualsiasi computer:
I componenti della scheda madre sono i dispositivi con i quali il kernel ed un qualsiasi sistema operativo dialogano, per ottenere informazioni, per eseguire delle operazioni, per modificare le impostazioni del computer che li ospita. Un microprocessore, chiamato anche CPU ( Central Processing Unit ) è una macchina calcolatrice installata su un unico chip: si tratta di un circuito elettronico ( o die ) il cui compito è quello di eseguire calcoli. Per eseguire calcoli sui dati, la CPU deve essere in grado anche di spostare questi dati. Il circuito elettronico, in sè, ha dimensioni ridottissime ( 1x1 cm, per un Pentium 4, contenente più di 120 milioni di transistori ), ma viene incapsulato in un contenitore di plastica molto più grande, che ospita i contatti elettrici, o piedini, o pin, che servono ad integrare il circuito alla scheda madre, attraverso il socket. Un processore, al contrario dei normali dispositivi elettronici, è programmabile. Un normale dispositivo elettronico viene progettato, a livello circuitazionale, per eseguire uno specifico compito. E solo quello. Un circuito così specilizzato viene definito hard wired, perchè per modificarne le funzioni si dovrebbe modificare, in tutto o in parte, l'architettura circuitazionale. Un processore, invece, può eseguire più funzioni, in base ad una serie di istruzioni lette da un programma. Questo tipo di approccio introduce una enorme flessibilità, soprattutto rispetto all'architettura hard-wired, sebbene comporti, ovviamente, una leggera penalizzazione, in termini prestazionali. Per ottenere questa pluralità di funzioni, l'organizzazione fisica ( hardware ) di una CPU deve essere molto più complessa, dovendo comprendere molti componenti elettronici:
Un processore multi-core è un unico componente fisico che contiene due o più unità computazionali indipendenti ( i cosiddetti core ), in grado di leggere ed eseguire istruzioni, in contemporanea, pur condividendo alcuni componenti, quali i BUS o la cache di secondo livello ( L2 ). I core possono essere installati, dal produttore, nello stesso circuito integrato ( die, o CMP, Chip Multiprocessor ), oppure in più circuiti integrati, riuniti in uno stesso package ( l'involucro che contiene il circuito elettronico ) di chip. Il PCI I/O BUS (o Local I/O Bus) è, oggi, il vero BUS di Input/Output: parte dal Southbridge e collega una serie di socket, chiamati slot, sui quali vengono montate delle schede hardware, o adattatori, alle quali vengono connessi i vari dispositivi ( vedi il diagramma di una motherboard ). Un BUS è composto da una parte hardware (i cavi fisicamente stesi tra una periferica o una scheda hardware e l'altra) e un'interfaccia software, programmabile. PCI (Peripheral Component Interconnec) è un vero e proprio protocollo software, composto da un insieme di specifiche che definisce le modalità di connessione e di interazione tra le varie componenti del sistema. L'architettura PCI fu introdotta per sostituire lo standard ISA (Industry Standard Architecture), con lo scopo dichiarato di migliorare le prestazioni nel trasferimento dei dati tra una periferica e la CPU, di essere il più indipendente possibile dalla piattaforma in uso, di semplificare l'inserimento e la rimozione delle periferiche. Per quanto riguarda le prestazioni, PCI ha BUS dati da 32 e 64 bit. Ricordiamo che ogni BUS è, in realtà, composto da tre BUS distinti: il bus dati (sulle cui linee corrono i bit dei dati da trasportare), il bus degli indirizzi (sulle cui linee corrono i bit degli indirizzi di memoria da cui prelevare o a cui inviare i dati da trasportare), i bus di controllo (sulle cui linee corrono i bit che indicano al kernel cosa sta avvenendo sui due BUS principali). I BUS dati ISA sui PC IBM avevano una larghezza di 8 bit; i BUS dati Universal ISA, usati oggi, hanno una larghezza di 16 bit. I BUS dati PCI che collegano processore e memoria, dai Pentium in poi, hanno una larghezza di 64 bit. La larghezza del BUS degli indirizzi è indipendente dalla larghezza del BUS dati e determina il numero delle locazioni di memoria raggiungibili. Il processore 8080, per esempio, aveva un bus degli indirizzi di larghezza 16 bit, pari a 65.536 byte di locazione di memoria indirizzabili. Il processore 8086 aveva un bus degli indirizzi di larghezza 20 bit, pari a 1.048.576 byte di locazione di memoria indirizzabili. Il processore 80286 aveva un bus degli indirizzi di larghezza 24 bit, pari a 16.777.216 byte di locazione di memoria indirizzabili (anche se, per motivi di compatibilità, permetteva l'accesso solo al primo megabyte di memoria, lasciando gli altri 15 megabyte disponibili come memoria espansa, prima, estesa, poi). I processori 80386 e 80486 avevano un bus degli indirizzi di larghezza 32 bit, pari a 4.294.967.296 byte di locazione di memoria indirizzabili. Il processore XEON ha un bus degli indirizzi di larghezza 36 bit, pari a 68.719.476.736 byte di locazione di memoria indirizzabili. Se dalla larghezza del bus dati dipende la quantità di dati che è possibile inviare su quel bus, la velocità del bus esprime la quantità di bit che ciascuna linea del bus può portare in un secondo. Molti bus trasmettono un solo bit per linea per ogni singolo ciclo di clock. Alcuni bus ad alte prestazioni, come AGP, sono in grado di trasportare due bit per linea per ciclo di clock, raddoppiando così le prestazioni. I bus più datati, quali ISA, possono aver bisogno di ben due cicli di clock per ciascun bit per ciascuna linea. Il bus PCI utilizza una frequenza di clock più elevata di quella usata da ISA: 25 MHz, 33 MHz, 66-MHz, fino a 133-MHz (il Front-Side bus). Nonostante il bus PCI possa raggiungere i 64 bit di larghezza e i 66 MHz in velocità, per motivi di compatibilità, la gran parte dei bus PCI utilizzano i 33 MHz per una larghezza di 32 bit. Moltiplicando la larghezza del bus per la velocità, otteniamo la quantità di dati (inviati in unità di 1 byte) che può essere teoricamente trasportata in un secondo. Per una frequenza di clock di 66 MHz ed una larghezza di 64 bit (8 byte) abbiamo:
Occorre ricordare che un MegaHertz è pari a 1.000.000 di Hertz, mentre un MegaByte è pari a 1.048.576 byte. Quindi, il calcolo corretto da fare è il seguente:
che è pari a:
che è il massimo transfer rate (o capacità di trasferimento, o bandwidth, o throughput) teorico del bus. Per quanto riguarda la semplificazione dell'inserimento e della rimozione delle periferiche, PCI supporta l'autorilevazione delle periferiche. Le periferiche PCI non hanno jumper e vengono automaticamente configurate in fase di boot del sistema (Plug and Play, o PnP). Plug and Play (PnP) permette di connettere una qualsiasi periferica al computer e vederla installata e configurata automaticamente, dal sistema operativo stesso, senza alcun nostro intervento. Affinchè PnP sia pienamente implementato, occorre che siano presenti un BIOS PnP, che rilevi l'esistenza di periferiche PnP e ne legga le impostazioni dal file ESCD (Extended System Configuration Data), memorizzato nella memoria nonvolatile del BIOS, un sistema operativo PnP, che supporti PnP, per completare il lavoro di configurazione iniziato dal BIOS, per ciascuna periferica, assegnando le necessarie risorse di sistema, quali gli IRQ (Interrupt request), l'accesso diretto alla memoria di sistema (DMA), una porzione di memoria dedicata, la selezione delle porte di I/O. I sistemi odierni sono dotati di almeno due BUS PCI: la CPU, così come la scheda video, è connessa al BUS PCI 0, il PCI BUS primario. Il bridge PCI-PCI connette il BUS primario al BUS secondario, il PCI BUS 1. Nelle specifiche PCI, il PCI BUS 1 viene descritto come posizionato downstream rispetto al bridge PCI-PCI, mentre il PCI BUS 0 viene indicato come la parte up-stream del bridge. L'intero sistema PCI è rappresentato come una struttura ad albero, in cui ciascun BUS è connesso al BUS superiore, fino ad arrivare alla radice dell'albero, il BUS 0. In realtà, le specifiche PCI permettono di ospitare, in uno stesso sistema, fino a 256 BUS. Nei grandi sistemi, questo numero è insufficiente. Linux, quindi, supporta i domini PCI, ciascuno dei quali può ospitare fino a 256 BUS. Ciascun BUS, a sua volta, può ospitare fino a 32 periferiche, ciascuna delle quali, a sua volta, può eseguire fino a otto funzioni differenti (periferica multifunzione). PCI è, come abbiamo già visto, indipendente dalla CPU. Quindi, tutte le periferiche che si trovano nel lato non CPU del controller PCI devono aderire alle specifiche PCI e non alle specifiche della CPU. Ciascuna periferica PCI viene identificata dal numero di BUS sul quale è installata, dal numero di periferica che il sistema le ha assegnato, dal numero di funzione che svolge. Il numero di funzione, in realtà, identifica una periferica che condivide lo stesso slot PCI con un'altra periferica PCI. L'esempio più semplice è una scheda di rete (NIC, o Network Interface Controller, oppure Network Interface Card), che potrebbe essere composta da due differenti NIC, ciascuna indipendente dall'altra. Il numero di funzione, quindi, permette di isolare le singole periferiche, anche se parte di una stessa periferica, alloggiata in un unico slot PCI. Il comando:
elenca tutte le periferiche PCI rilevate nel sistema:
Numero di BUS, numero di periferica e numero di funzione appaiono nel primo campo dell'output, composto da 16 bit, relativo al posizionamento della periferica sul BUS PCI:
Il comando lspci, in questo esempio, omette un'informazione aggiuntiva, che è il numero del dominio di appartenenza, omesso semplicemente perchè in questo sistema esiste un solo dominio. Nel caso esistessero più domini, o utilizzando l'opzione -D tale informazione apparirebbe nei primi 16 bit aggiuntivi:
Quindi, il primo campo dell'output completo del comando lspci, quello relativo al BUS di appartenenza, è composto da:
I numeri sono espressi in notazione esadecimale. Il numero del BUS esprime la distanza della periferica dal Front Side Bus (CPU), mentre il numero di periferica rappresenta la posizione della periferica lungo il BUS di appartenenza:
I campi successivi dell'output del comando lspci sono dedicati alla periferica stessa e sono:
Per esempio:
dove:
rappresenta la classe (con sottoclasse) di appartenenza:
mentre:
rappresenta l'identificativo (ID) del produttore:
mentre:
rappresenta l'identificativo (ID) del prodotto:
con il numero di versione del firmware. In questo esempio, la periferica è un Host Bridge: si tratta del bridge che connette tutte le periferiche e i BUS PCI al processore e alla memoria di sistema. Dove prende, il sistema operativo, queste informazioni relative all'hardware installato? Queste informazioni vengono conservate in uno spazio di memoria, assegnato a ciascuna delle periferiche PCI installate, chiamato configuration space (spazio di configurazione). Ciascuna periferica PCI, compreso il bridge PCI-PCI, ha memorizzato, in un qualche punto dello spazio di memoria, una struttura di dati di configurazione. L'header di configuazione PCI permette al sistema di identificare e controllare ciascuna periferica PCI presente nel sistema ed è la struttura portante del meccanismo del Plug and Play. CPU e periferiche PCI devono poter accedere alla memoria del sistema (RAM). La memoria viene utilizzata dai vari driver di periferica per mantenere i registri di controllo e di stato relativi a ciascuna periferica. Naturalmente, le periferiche PCI non possono avere accesso a tutta la memoria del sistema, altrimenti ad ogni loro accesso, la CPU dovrebbe rimanere in attesa per accedere, a sua volta, alla memoria. Le periferiche PCI, quindi, si vedono assegnare un loro spazio di memoria (mentre il loro accesso alla memoria di sistema è possibile solo utilizzando i canali DMA, o Direct Memory Access). Le periferiche ISA hanno accesso a due spazi di indirizzi di memoria, lo spazio ISA I/O (Input/Output) e lo spazio di memoria. Le periferiche PCI, invece, hanno accesso a tre spazi di memoria, uno dei quali dedicato ai dati di configurazione di ciascuna periferica. Le locazioni di memoria e le porte I/O (Input/Output) sono condivise tra tutte le periferiche installate lungo lo stesso BUS PCI, mentre lo spazio di configurazione sfrutta l'indirizzamento di tipo geografico. Ciascuno slot PCI ha un suo spazio di configurazione. Quindi, il primo slot PCI potrebbe avere il proprio spazio di configuazione all'offset 0 (zero) di memoria, mentre il secondo slot PCI potrebbe averlo all'offset 256. Il numero di slot PCI è il numero di periferica ("Device Number"), mentre il numero di funzione indica il tipo di periferica installata nello slot PCI. Una scheda hardware, installata su uno slot PCI, può contenere fino a 8 periferiche distinte. Ciascuna di queste 8 periferiche rappresenta una funzione. Quello che Linux chiama "device" (periferica), in linguaggio PCI è chiamato "function" (funzione). Le funzioni, quindi, vengono numerate da 0 a 7. La sequenza di numeri:
dove PCI rappresenta il numero di BUS lungo il quale la periferica è installata, rappresenta un indirizzo geografico, poichè identifica un preciso spazio della memoria, in cui è conservato lo spazio di configurazione della singola periferica. Per esempio, la sequenza:
indica la periferica installata sul BUS PCI 0, slot 0d, funzione 2. Uno spazio di configurazione è composto da 256 byte ed è suddiviso in registri. I primi 64 byte dello spazio di configurazione rappresentano l'header e devono contenere le informazioni richieste dallo standard PCI, mentre i restanti 192 byte vengono utilizzati dalla periferica stessa. In realtà, l'output del comando lspci restituisce, di default, i numeri ID, del produttore e del prodotto, già risolti, mentre per avere la sequenza dei dati in valore numerico occorre specificare l'opzione n:
oppure la doppia opzione nn, per avere entrambe le rappresentazioni (numerica e testuale):
Il kernel ed il sistema operativo Il termine Sistema Operativo viene, normalmente, utilizzato con due significati differenti:
Sebbene sia possibile eseguire programmi in un computer senza un kernel, la presenza di un kernel semplifica, di molto, la creazione e l'utilizzo di altri programmi, mettendo a disposizione del programmatore un insieme di software che permette di gestire le limitate risorse di un computer. Il file eseguibile del kernel Linux si trova, solitamente, in:
o qualcosa di simile. Nelle prime implementazioni UNIX, il kernel era chiamato unix. Poi, venne introdotta la memoria virtuale (virtual memory) ed il kernel venne chiamto vmunix. In Linux, il nome del file copia l'originale, sostituendo con la lettera z la lettera finale x, ad indicare che l'eseguibile del kernel è un eseguibile compresso. Ecco i principali compiti del kernel:
Il kernel decide quale processo avrà accesso alla CPU e per quanto tempo. Il kernel mantiene una struttura di dati in cui conserva le informazioni su tutti i processi in esecuzione, una struttura che mantiene aggiornata ogni qualvolta vengono creati nuovi processi, o un processo cambia stato oppure termina. Il kernel mantiene tutti i dati che permettono di tradurre i nomi di file usati dai programmi in locazioni fisiche del disco fisso. Il kernel mantiene tutti i dati che traducono (mappano) la memoria virtuale assegnata a ciascun processo in indirizzi fisici di memoria e di area di swap su disco fisso. Tutte le comunicazioni tra processi differenti vengono rese possibili dal kernel. Il kernel crea nuovi processi e ne termina altri in esecuzione. Il kernel (in particulare, i driver di periferica) comunica con le periferiche di input e output.
Quando si sentono dire cose del tipo: “un processo può creare un altro processo”, “un processo può creare un pipe”, “un processo può scrivere dati in un file”, “un processo può terminare invocando
Le due modalità possono essere invocate attraverso istruzioni hardware. Analogamente, le aree di memoria virtuale possono essere marcate come aree appartenenti allo user space, oppure al kernel space. Quando opera in user mode, la CPU può accedere solo alle aree di memoria marcate come appartenenti allo user space; i tentativi di accedere alle aree di memoria appartenenti al kernel space producono una hardware exception. Quando opera in kernel mode, la CPU può accedere sia alle aree di memoria appartenenti allo user space, sia alle aree di memoria appartenenti al kernel space. Certe operazioni possono essere eseguite, dalla CPU, esclusivamente in kernel mode: l'istruzione halt, per spegnere il sistema, oppure l'accesso all'hardware di gestione della memoria, oppure, ancora, l'inizializzazione delle operazioni di I/O. Grazie a questa architettura hardware che permette di portare il sistema operativo al livello del kernel space, i programmatori di sistemi operativi possono assicurarsi che i processi utente non siano in grado di accedere alle istruzioni e ai dati del kernel, oppure di effettuare operazioni che possano incidere sulle operazioni del sistema. La Linux Kernel Organization è una organizzazione ( California Public Benefit Corporation ) fondata nel 2002, la cui missione è la distribuzione gratuita del kernel Linux, oltre ad altro software Open Source, all'utenza. È gestita dalla Linux Foundation, che le fornisce un pieno supporto tecnico e finanziario nel mantenimento di kernel.org. Il sito web kernel.org è la fonte ufficiale de facto per i sorgenti del kernel Linux. Molte distribuzioni Linux ( come Ubuntu ) creano i loro kernel dedicati, che spesso non sono fondati sui kernel ufficiali, quelli scritti dagli sviluppatori aderenti alla Linux Kernel Organization. Queste release (versioni) non vengono ospitate da kernel.org. Gli sviluppatori dei kernel ufficiali, quindi, non possono offrire alcun supporto per queste release dedicate. Come sapere se voi state eseguendo un kernel di una particolare distribuzione Linux ( e non un kernel ufficiale )? Se voi non avete mai scaricato, compilato ed installato una versione del kernel dalle pagine web di kernel.org, allora state utilizzando un kernel di una distribuzione Linux qualsiasi. Per conoscere la versione del kernel in esecuzione sul vostro computer, eseguite il comando:
Se vedete una qualsiasi cosa dopo il trattino:
allora state eseguendo un kernel di una distribuzione. Per sapere di quale distribuzione e conoscerne la versione, eseguite il comando:
Cos'è una distribuzione Linux? Una distribuzione Linux è un predeterminato insieme di appicazioni, affiancato ad un kernel Linux. Una distribuzione Linux permette agli utenti di installare un sistema operativo Linux, senza doversi sobbarcare l'onere di crearselo da soli, selezionando i moduli e le applicazioni ritenute indispensabili. Una distribuzione Linux ha già preselezionato i moduli e le applicazioni da installare. Probabilmente, tra questi moduli e queste applicazioni, ce ne saranno alcune che non utilizzeremo mai, di cui, probabilmente, non conosceremo mai l'esistenza. E, spesso, queste applicazioni e questi moduli tengono impegnate risorse di sistema. Quante distribuzioni Linux esistono? Una miriade! Anche perchè la gran parte del software incluso in una distribuzione Linux viene rilasciata con licenza GNU General Public License (GPL), permettendo a chiunque di costruirsi la propria distribuzione personale. Ma la gran parte degli utenti, in realtà, utilizza una distribuzione scelta tra una manciata di distribuzioni molto popolari e diffuse, quali Debian, Ubuntu, Fedora, Red Hat, oppure una distribuzione fondata su una di queste ultime ( Ubuntu, per esempio, è un derivato di Debian ). Un sito di riferimento per tutte le distribuzioni Linux esistenti è distrowatch.com. Una distribuzione è caratterizzata, normalmente, da un Package Manager, un software che gestisce l'installazione e l'aggiornamento dei singoli componenti di quella particolare distribuzione Linux. I Package Manager più noti sono RPM e APT (fondata su DPKG, il Package Manager originale della distribuzione Debian). L'alternativa alle distribuzioni Linux esistenti è la creazione di una propria distribuzione, attraverso l'accurata selezione dei moduli e delle applicazioni da inglobarvi. Il progetto Linux From Scratch è una guida alla costruzione di una distribuzione Linux. Costruire una propria distribuzione Linux significa compilare tutto direttamente dal codice sorgente, senza utilizzare i package binari precompilati. Il progetto Linux From Scratch concentra in un libro tutte le informazioni e le istruzioni necessarie alla progettazione ed alla realizzazione del proprio sistema operativo. Nella home page di kernel.org, c'è il link alla versione più recente, ufficiale e “stable” del kernel Linux. Se desiderate installarla, scaricate il file compresso, che solitamente ha estensione tar.xz, per esempio:
Per decomprimere il file, eseguite il comando:
sapendo che per ogni tipo di file compresso, tar richiede una differente opzione:
Dopo la decompressione, troverete la directory corrente popolata da migliaia tra file e sottodirectory, tra i quali troverete molti file txt che, pur non essendo sempre aggiornati alla versione più recente, sono un ottimo punto di partenza per comprendere il funzionamento e la struttura del kernel. Il primo file dal quale attingere informazioni è il file README della cartella principale. Nel caso della versione 4.9 del kernel, per esempio, il file README della directory principale dice: "Leggete con cura queste note relative a Linux, versione 4, poichè in queste note vi si dice di cosa si sta trattando, vi si spiega come installare il kernel e cosa fare nel caso qualcosa andasse storto. All'interno della sottodirectory:
troverete molti file README, che, normalmente, contengono informazioni sull'installazione, specifiche di un particolare kernel, per esempio di un qualche driver. Leggete il file:
per un elenco dei file e di cosa contiene ciascun file. Leggete il file:
che contiene informazioni sui problemi che potrebbero sorgere nell'aggiornare il vostro kernel". Due sono le raccomandazioni da tenere bene a mente:
Linux permette di estendere le funzionalità del kernel, attraverso il caricamento, in fase di esecuzione ( runtime ), di moduli personalizzati. Un modulo è un "object code", un pezzo di codice in linguaggio macchina non richiamato (linked) da alcun programma. Un esempio di modulo è il driver di periferica. Il kernel Linux viene eseguito in una specifica area di memoria e in uno spazio di indirizzi condiviso. Una volta caricato, un modulo diventa parte del kernel, condividendo lo stesso spazio degli indirizzi del codice incluso nel kernel al momento della compilazione. I moduli possono essere compilati come loadable modules oppure già caricat dal kernel. I loadable modules possono essere caricati e scaricati dalla memoria con il kernel in esecuzione, senza che sia necessario eseguire il reboot del sistema. Tutti i moduli presenti nel vostro computer sono conservati in:
e possono essere visualizzati con il comando:
Il comando restituisce tutti i moduli presenti nel sistema: ma non tutti sono stati caricati in memoria. Per sapere quali moduli sono attualmente caricati, eseguite:
Per caricare in memoria un modulo, eseguite:
Il modulo, a questo punto, viene caricato in memoria, fino al termine della sessione di lavoro, oppure fino al comando successivo di rimozione dal kernel:
modprobe è parte del package kmod. Normalmente, i moduli vengono caricati da udev (device manager), su richiesta. Anche i moduli possono prevedere delle dipendenze. Per sapere se e quali dipendenze un modulo richiede, eseguite:
Per sapere quale driver e quali moduli richiede ciascuna componente hardware, eseguite il comando:
In questo modo, potreste scoprire che l'interfaccia Ethernet controller: Qualcomm Atheros AR8152 v2.0 Fast Ethernet (rev c1) richiede:
A questo punto, sarà sufficiente verificare se driver e modulo sono già caricati in memoria:
La risposta è: si. Normalmente, si desidera che un modulo venga caricato in memoria durante il boot del sistema. È possibile inserire, a questo fine, il nome del modulo all'interno di un file di configurazione, che può avere un nome qualsiasi, ma l'estensione .conf, all'interno della directory:
In un sistema Linux, un processo non accede mai direttamente alla memoria fisica del sistema ( RAM ), ma si vede assegnare, dal kernel, uno specifico spazio virtuale di memoria ( virtual address space ), o spazio virtuale degli indirizzi di memoria. A prescindere dall'organizzazione fisica sottostante, uno spazio virtuale degli indirizzi di memoria, assegnato ad un processo, ha inizio con l'indirizzo zero e continua, in modo lineare, fino al raggiungimento del numero massimo degli indirizzi assegnati. Uno spazio virtuale degli indirizzi è composto da unità di 4 o di 8 Kilobyte, a seconda dell'architettura ospitante, a 32 o 64 bit, chiamata page ( pagina ).
|
|||||
I comandi Linux: il sistema | The .bit guides: original contents |