Linus contro Tanenbaum: come un hobby «non grande né professionale» è diventato Linux
MINIX, un 386 comprato a rate, «just a hobby» e la flame war «LINUX is obsolete»: microkernel contro monolitico, e come alla fine hanno vinto tutti e due.
Il 25 agosto Linux ha compiuto 34 anni. Per festeggiare, raccontiamo come è nato: un ventunenne finlandese, un professore olandese con la barba e le idee molto chiare, un newsgroup Usenet e una delle flame war più famose della storia dell'informatica. Spoiler: avevano ragione entrambi, e a vincere sono stati tutti e due. Più o meno.
Antefatto: un professore, un libro e 12.000 righe di C
Nel 1987 Andrew S. Tanenbaum, professore alla Vrije Universiteit di Amsterdam, ha un problema didattico. Unix è il sistema operativo che vale la pena studiare, ma dalla Version 7 in poi AT&T ha smesso di permettere che il suo codice sorgente venga insegnato nelle università. Il celebre commentario di Lions, che spiegava riga per riga il kernel di Unix V6, circola solo in fotocopie semiclandestine, di quarta generazione.
La soluzione di Tanenbaum è da ingegnere: se non posso usare Unix, me lo riscrivo. Nasce così MINIX (mini-Unix): compatibile con le syscall di Unix V7, circa 12.000 righe di codice, distribuito insieme al libro Operating Systems: Design and Implementation. Gira sull'IBM PC con un 8088, senza MMU e con 640 KB di RAM nella migliore delle ipotesi.
La caratteristica chiave di MINIX è architetturale: è un microkernel. Il kernel vero e proprio fa pochissimo (scheduling, interrupt, scambio di messaggi), mentre il file system e la gestione della memoria sono processi separati che comunicano tramite messaggi. È pulito, è elegante ed è facile da spiegare a lezione. Ha però due limiti: Tanenbaum lo vuole piccolo e didattico, quindi rifiuta la maggior parte delle patch, e la licenza permette di leggere e studiare il codice ma non di ridistribuirlo modificato.
1991: un 386, un modem e un disco sacrificato
Il 5 gennaio 1991 Linus Torvalds, studente di informatica all'Università di Helsinki, compra a rate un PC con un Intel 80386DX a 33 MHz, 4 MB di RAM e un disco da 40 MB. Ci installa MINIX (arrivato per posta dopo settimane, su floppy) e comincia a lamentarsi. Il terminale gli sembra scarso e vorrebbe sfruttare davvero il 386: la modalità protetta a 32 bit, la paginazione e il task switching in hardware.
Il primo programma non è un sistema operativo: è un test del task switching del 386, scritto in assembly e avviato direttamente dal boot, senza MINIX sotto. Due task: uno stampa A, l'altro B, e un interrupt del timer li alterna. Il risultato è una schermata di AAAABBBBAAAABBBB, e chiunque abbia mai scritto uno scheduler sa che è un momento bellissimo.
Da lì il progetto cresce un pezzo alla volta. I due task diventano un emulatore di terminale (uno legge dalla tastiera e scrive sul modem, l'altro legge dal modem e scrive sullo schermo) per collegarsi al server dell'università e leggere Usenet. Poi a Linus serve scaricare file, quindi scrive un driver per il disco. Poi gli serve un file system, e sceglie quello di MINIX per poter condividere i dati. A un certo punto si accorge che il suo emulatore di terminale ha sempre più l'aspetto di un kernel.
Secondo il racconto dello stesso Linus, in quel periodo commette anche un errore memorabile: vuole far comporre un numero al modem e invece scrive sul device del disco, sovrascrivendo la partizione MINIX con i comandi AT. A quel punto la scelta è tra reinstallare MINIX o rendere il suo kernel capace di compilare se stesso. Indovinate cosa sceglie.
25 agosto 1991: «solo un hobby»
Il messaggio con cui Linux viene annunciato al mondo, sul newsgroup comp.os.minix, è probabilmente il caso di understatement più riuscito della storia dell'ingegneria:
Hello everybody out there using minix - I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones. [...] I've currently ported bash(1.08) and gcc(1.40), and things seem to work.
Nello stesso messaggio Linus aggiunge che il sistema «is NOT portable (uses 386 task switching etc), and it probably never will support anything other than AT-harddisks, as that's all I have :-(». Oggi Linux gira su una ventina di architetture, dai microcontrollori ai mainframe IBM Z, e su tutti i 500 supercomputer della TOP500. Tutto calcolato, ovviamente.
Il 17 settembre 1991 la versione 0.01 finisce sul server FTP ftp.funet.fi. Linus voleva chiamarla Freax (free + freak + x) e considerava "Linux" un nome troppo egocentrico. Ari Lemmke, l'amministratore del server, non apprezza "Freax" e crea la directory pub/OS/Linux. Il nome resta quello. Più o meno è la storia di ogni nome in informatica: lo decide chi crea la directory.
La 0.01 contiene circa 10.000 righe di codice. Per compilarla serve MINIX, e il kernel non può ancora essere usato in modo indipendente. L'annuncio della 0.02, il 5 ottobre, ha però già il tono giusto:
Do you pine for the nice days of minix-1.1, when men were men and wrote their own device drivers?
Come era fatto, tecnicamente
Linux 0.01 è un kernel monolitico nel senso più letterale: scheduler, gestione della memoria, file system, driver di tastiera, console, seriale e disco girano tutti nello stesso spazio di indirizzamento, al ring 0 del 386, e si chiamano a vicenda con semplici chiamate di funzione C. Alcuni dettagli che oggi fanno sorridere:
- il cambio di contesto usa direttamente il task switching hardware del 386 (TSS e un
ljmpverso il selettore del task), una scelta che Linux abbandonerà più avanti, quando il cambio di contesto via software si rivelerà più veloce; - il numero di processi è fisso:
NR_TASKSvale 64, ed è un array statico; - la memoria è divisa in segmenti da 64 MB per processo, sfruttando la segmentazione del 386 insieme alla paginazione;
- la tastiera è configurata per il layout finlandese/svedese, perché era quello che Linus aveva sulla scrivania.
La differenza con MINIX si vede bene seguendo una banale read(). In Linux il percorso è tutto interno al kernel:
/* Linux (monolitico): un'unica trap, poi solo chiamate di funzione */
read(fd, buf, n)
└─ int 0x80 /* entra nel kernel, ring 0 */
└─ sys_read()
└─ file_read() /* file system, stessa memoria */
└─ bread() /* buffer cache */
└─ ll_rw_block() /* driver del disco: un'altra funzione */In MINIX la stessa operazione è uno scambio di messaggi tra processi diversi:
/* MINIX (microkernel): la libc confeziona un messaggio */
message m;
m.m_type = READ;
m.m1_i1 = fd; m.m1_i2 = n; m.m1_p1 = buf;
sendrec(FS, &m); /* trap: il kernel copia il messaggio al processo FS */
/* FS (processo utente) -> sendrec al task del disco -> interrupt -> risposta
-> il kernel copia i dati -> risposta all'utente.
Ogni freccia è un cambio di contesto e una copia di messaggio. */Nel primo caso ogni passaggio costa quanto una call. Nel secondo costa un passaggio dal kernel, una copia e un cambio di contesto. Sul 386 del 1991, senza cache L2 degna di questo nome e con TLB che si svuotano a ogni cambio di spazio di indirizzamento, è una differenza enorme. È qui che inizia la lite.
29 gennaio 1992: «LINUX is obsolete»
Tanenbaum, che di sistemi operativi ne sa parecchio, guarda il kernel che sta spopolando sul newsgroup del suo sistema operativo e pubblica un messaggio dal titolo che non lascia spazio a dubbi: «LINUX is obsolete». Le sue critiche sono due, ed entrambe serie:
- Architettura. Secondo Tanenbaum la discussione tra microkernel e kernel monolitici è chiusa da anni, e i microkernel hanno vinto. Un kernel monolitico nel 1991 è «un enorme passo indietro, agli anni '70».
- Portabilità. Legare un sistema operativo a una CPU, e per di più a una CPU strana come l'x86, è per lui «fondamentalmente sbagliato». Il futuro sono i RISC: SPARC, MIPS e simili. Fa anche una previsione molto precisa: tra cinque anni tutti useranno GNU libero su una SPARCstation-5 da 200 MIPS e 64 MB.
In un messaggio successivo aggiunge la frase che tutti ricordano: «Be thankful you are not my student. You would not get a high grade for such a design :-)». In pratica: bocciato, ma con lo smile.
Linus ha 22 anni e la diplomazia di chi ne ha 22. La sua risposta si apre con un «Well, with a subject like this, I'm afraid I'll have to reply». Ammette che «from a theoretical (and aesthetical) standpoint linux looses», ma sostiene che Linux batte MINIX in quasi tutto ciò che conta nella pratica. Poi arriva la frase che diventerà leggenda: «Your job is being a professor and researcher: That's one hell of a good excuse for some of the brain-damages of minix».
Nella discussione intervengono anche Ken Thompson, uno dei creatori di Unix, e molti altri. Il thread va avanti per settimane. Alla fine Linus si scusa per i toni, Tanenbaum resta della sua idea, e tutti tornano a scrivere codice. Oggi i flame su Usenet si chiamano "discussioni su GitHub" e funzionano esattamente allo stesso modo.
Chi aveva ragione?
Tecnicamente: entrambi, in modi diversi.
Tanenbaum aveva ragione sui principi. Isolare i driver in processi separati rende il sistema più robusto, ed è vero che nei kernel monolitici la maggior parte dei crash arriva dai driver. Inoltre i microkernel moderni hanno dimostrato che l'IPC non deve per forza essere lento: nel 1993 Jochen Liedtke con L4 porta il costo dell'IPC a una frazione di quello di Mach, e nel 2009 seL4 diventa il primo kernel general purpose con una prova formale di correttezza. QNX, un microkernel, gira da decenni nei sistemi critici e nelle automobili.
Aveva torto sulla CPU. L'x86 non è sparito: si è mangiato i RISC delle workstation, e poi i server. Anche GNU non è arrivato: il kernel Hurd, un microkernel basato su Mach, nel 2025 non ha ancora raggiunto la versione 1.0. In compenso Linux, nato "non portabile", è diventato il kernel portato su più architetture della storia.
Linus aveva ragione sull'ingegneria. Un sistema che funziona oggi, su hardware che la gente possiede, con un modello di sviluppo aperto, batte un sistema elegante che non accetta patch. Il kernel è rimasto monolitico ma è diventato modulare. Ha introdotto i moduli caricabili a metà degli anni '90 e, negli anni, si è preso un po' di idee dei microkernel:
- FUSE (2005): file system in user space, cioè esattamente quello che faceva MINIX;
- UIO/VFIO: driver in user space, usati da DPDK e dalle macchine virtuali con passthrough;
- eBPF: codice caricato a runtime nel kernel, ma verificato prima di essere eseguito;
- sched_ext (6.12, 2024): scheduler scritti come programmi BPF e sostituibili a caldo.
Del resto, anche i "monolitici" famosi non lo sono del tutto. XNU (macOS/iOS) è Mach più BSD nello stesso spazio di indirizzamento, e Windows NT si definisce "ibrido". Il dibattito non si è chiuso: tutti hanno preso qualcosa dagli altri.
Il vero colpo di scena: la GPL
Se c'è un motivo per cui Linux ha vinto, non è tecnico ma legale. La prima licenza di Linux vietava qualsiasi uso commerciale, anche solo far pagare la copia su floppy. Con la versione 0.12, all'inizio del 1992, Linus annuncia il passaggio alla GNU GPL v2: chiunque può usare, modificare e ridistribuire il codice, purché le modifiche restino libere.
Mancava proprio questo pezzo. Il progetto GNU aveva già il compilatore, la shell, le coreutils e la libc, ma non un kernel funzionante. Linux aveva il kernel ma nient'altro. Insieme fanno un sistema operativo completo, e da lì nascono le distribuzioni: SLS, poi Slackware e Debian nel 1993. MINIX, nel frattempo, resta un sistema didattico con una licenza restrittiva (diventerà libero solo nel 2000, con licenza BSD).
Il 14 marzo 1994 esce Linux 1.0, con circa 176.000 righe di codice. Oggi, con la 6.16 uscita a fine luglio, il kernel ne ha più di 30 milioni, migliaia di contributori per ogni release e una nuova versione ogni nove o dieci settimane. Non male, per un hobby che non sarebbe mai diventato grande e professionale.
Epilogo: chi ride per ultimo
Nel 1996 Linux sceglie una mascotte: un pinguino disegnato da Larry Ewing con GIMP. Linus racconta di essere stato beccato da un pinguino in uno zoo in Australia, e da allora di averli in simpatia. Si chiamerà Tux.
MINIX invece ha un finale da romanzo. Nel 2005 Tanenbaum rilascia MINIX 3, un microkernel pensato per l'affidabilità: se un driver va in crash, un server di "reincarnazione" lo riavvia senza fermare il sistema. Dal 2015 MINIX 3 gira, senza che quasi nessuno lo sappia, dentro l'Intel Management Engine, il microcontrollore nascosto presente nei chipset Intel. Nel 2017 Tanenbaum scrive una lettera aperta a Intel per dire che gli avrebbe fatto piacere saperlo, e che MINIX è con ogni probabilità il sistema operativo più diffuso al mondo sui computer x86.
Quindi, se avete un PC Intel recente, al suo interno ci sono due sistemi operativi: Linux (o il sistema che preferite) e, sotto, nascosto, MINIX. Tanenbaum e Linus, dopo trent'anni, condividono la stessa macchina. Tanenbaum ha anche ottenuto il ring più privilegiato.
Riassunto per chi ha scrollato fino a qui
| Data | Evento | Commento |
|---|---|---|
| 1987 | MINIX 1.0 + libro di Tanenbaum | Unix didattico, microkernel, 12k righe |
| gen 1991 | Linus compra un 386 | Il task switching hardware come primo amore |
| 25 ago 1991 | «just a hobby, won't be big and professional» | La previsione meno accurata della storia |
| 17 set 1991 | Linux 0.01 su ftp.funet.fi | Doveva chiamarsi Freax |
| 29 gen 1992 | «LINUX is obsolete» | La flame war più citata di sempre |
| inizio 1992 | Linux 0.12 → GPL v2 | Il vero motivo della vittoria |
| 14 mar 1994 | Linux 1.0 | 176k righe, oggi più di 30 milioni |
| 2015–2017 | MINIX 3 dentro Intel ME | Tanenbaum gira su più CPU x86 di Linus |
Morale ingegneristica: si può avere ragione in teoria e torto in pratica, o il contrario, e a volte entrambe le cose nello stesso thread. E comunque, ogni volta che lanciate un container, state usando i namespace di un kernel monolitico "obsoleto" dal 1992.
Alla prossima storia di bit. 🐧