Lo scopo di questa conversione è quello di rimanere con un sistema
che sia in grado di costruire e di far girare i programmi in ELF e
col sistema a.out, con entrambe i tipi di programmi in grado di
trovare le rispettive famiglie di librerie condivise. Questo ovviamente
richiede un pò più di intelligenza nella ricerca delle librerie rispetto
al semplice `guarda in /lib
, /usr/lib
e in tutti i posti
in cui il programma è stato detto di cercare'.
La bestiola responsabile di ricercare le librerie in linux è
/lib/ld.so
. Il compilatore ed il linker non inseriscono nel codice
i percorsi assoluti delle librerie dentro i programmi; inseriscono invece
il nome delle librerie, e il percorso assoluto di ld.so
, e lasciano
che sia ld.so
ad associare il nome della libreria al percorso adeguato
al runtime. Questo ha un effetto molto importante --- significa che le
librerie che un programma usa, possono essere mosse verso altre directory
senza ricompilare il programma , semprechè a ld.so
sia stato
detto di cercare nelle nuove directory. Questa è una funzionalità essenziale
per l'operazione di scambio delle directory che segue.
Ne consegue che, naturalmente, ogni tentativo di cancellare o spostare
ld.so
causerà il fatto che ogni programma che sia linkato
dinamicamente sul sistema linux, cesserà di funzionare. Questa è
generalmente ritenuta una cattiva cosa...
Per il codice binario in ELF, viene fornito un dynamic loader (caricatore
dinamico del codice) alternativo. Si chiama /lib/ld-linux.so.1
,
e fa esattamente le stesse cose di ld.so
, ma per i programmi in ELF.
ld-linux.so.1
usa gli stessi programmi e gli stessi file di supporto
(ldd
, ldconfig
, e /etc/ld.so.conf
, che vengono usati
dal loader del formato a.out.
L'idea di base, poi, è che le cose che riguardano lo sviluppo in ELF
(compilatori, include files e librerie) vadano in
/usr/{bin,lib,include}
dove attualmente si trovano quelle
che riguardano l'a.out, e che queste ultime vadano spostate in
/usr/i486-linuxaout/{bin,lib,include}
.
/etc/ld.so.conf
farà una lista di tutti i posti dove ci si
può aspettare di trovare una libreria, e ldconfig
è abbastanza
intelligente da distinguere tra le varianti di ELF e di a.out.
Ci sono un paio di eccezioni al piazzamento delle librerie, tuttavia.
ld.so
. Questi cesseranno di funzionare se le loro librerie saranno
spostate. In questo modo, libc.so*
e libm.so*
devono rimanere
dove stanno in /lib
, e le versioni in ELF avranno il loro major
number aumentato, in maniera da non sovrascrivere le versioni per
a.out. Le vecchie librerie per X (precedenti alla versione 6), è meglio
lasciarle dove stanno, sebbene le più nuove (libX*.so.6
) debbano essere
spostate. Lo spostamento delle vecchie librerie causerà un apparente
malfunzionamento dei programmi xview, mentre non spostare le nuove librerie,
causerà la sovrascrittura quando si installeranno le librerie in ELF per
X.
Se si hanno programmi non-ld.so che richiedono altre librerie
rispetto a quelle già citate, (se si sa quali programmi sono, si può
far girare ldd su di loro per capire di quali librerie abbiano
bisogno prima di rovinarli), allora si hanno essenzialmente due
possibilità. La prima è che si possono estrarre i file tar in una directory
temporanea, controllare se le proprie preziose librerie saranno sovrascritte,
e, se così fosse, si sposterà la versione in ELF della libreria in,
diciamo, /usr/i486-linux/lib
invece che /lib
.
Sia sia sicuri che il proprio ld.so.conf
abbia
/usr/i486-linux/lib
, e si faccia girare ldconfig
e non ci si pensi più. La seconda cosa è che si può ricompilare o acquisire una
copia più recente del programma che crea questa seccatura. Questa
non sarebbe affatto una cattiva idea, se possibile.
/usr
e /
su differenti partizioni,
sarà necessario muovere almeno alcune delle librerie in /lib
da qualche parte sul root disk, non in /usr
. Si può sia
identificare i programmi necessari al system startup o quando si è in
modo single user (singolo utente), e trovare le librerie che usano, oppure
può dipendere dal vostro integratore del sistema o della distribuzione,
che può aver già fatto questo per voi, e semplicemente spostare tutte
(beh... alcune. Si veda quanto già detto per le eccezioni) le librerie
da /lib
a /lib-aout
.
mv
, ln
, e forse
anche di altre utility per la manipolazione dei file (sebbene di fatto
possa essere fatto tutto quello di cui si ha bisogno con le
possibilità intrinseche della shell), per ogni situazione scomoda
in cui si può finire.
/lib/elf
(tipicamente libc.so.4
e compagnia varia).
Le applicazioni costruite in questa maniera devono essere ricostruite,
e poi la directory rimossa. Non è necessario avere una directory
/lib/elf
!
/sbin/
qualcosa e non si ha una directory /sbin
,
propabilmente si troveranno i programmi relativi in
/bin
o in /etc/
.
I seguenti pacchetti sono disponibili a ftp://tsx-11.mit.edu/pub/linux/packages/GCC/ e a ftp://sunsite.unc.edu/pub/Linux/GCC/. Entrambe i siti sono ampiamente distribuiti in giro per il mondo; per favore, prendetevi il tempo necessario per cercare il sito più vicino a voi. E` più veloce per voi e per chiunque altro.
Questi pacchetti (sia la versione mostrata qui che qualunque altra successiva)
sono richiesti. Scaricate e leggete anche le varie release notes per ciascuno
di essi: questi sono i file chiamati release.
packagename.
Questo specialmente se si scaricano versioni più recenti di quelle
descritte qui, poichè la procedura può essere cambiata.
ld.so-1.7.3.tar.gz
--- il nuovo linker dinamico
libc-5.0.9.bin.tar.gz
--- le immagini ELF condivise per
la libreria C e i suoi amici (m
(maths), termcap
, gdbm
, e
così via), più le librerie statiche corrispondenti e gli include files
necessari per compilare i programmi con queste. libc 5.2.qualcosa potrebbe
essere rilasciata durante la vita di questo HOWTO, ed è notevolmente
differente dalla versione 5.0.9; se si intende installarla, si procede
per conto proprio, ma io raccomando di installare prima la 5.0.9 e poi
installare `sopra' la versione successiva. Ci sono molte parti della
5.0.9 che non sono incluse nella 5.2.x, per le quali i canali di
distribuzione non sono ancora predisposti completamente.
gcc-2.7.0.bin.tar.gz
--- il compilatore C in ELF. Include
anche un compilatore C in a.out che capisce il nuovo ormato delle directory.
binutils-2.5.2l.17.bin.tar.gz
--- le utility binarie della GNU
per Linux. questi sono programmi come gas
, ld
, strings
e così
via, la maggior parte dei quali sono richiesti per far funzionare il
compilatore C.
Bene.... Si noti che in tutto quel che segue, quando io dico `si rimuova', naturalmente intendo `si faccia un backup e poi si rimuova' :-). Inoltre, queste istruzioni si applicano direttamente soltanto alle persone che non hanno già smanettato con l'ELF --- quelli che ci si aspetta abbiano già la capacità di adattare le cose in modo appropriato. Andiamo!
mkdir -p /usr/i486-linuxaout/bin
mkdir -p /usr/i486-linuxaout/include
mkdir -p /usr/i486-linuxaout/lib
mkdir /lib-aout
ld.so-1.7.3
nella directory in cui di solito si mette il codice sorgente, poi si legga
lo script ld.so-1.7.3/instldso.sh
appena estratto.
Se si ha un sistema realmente standard, è sufficiente farlo girare
digitando sh instldso.sh
, ma se si ha qualcosa di insolito
allora si faccia l'installazione a mano. `Qualcosa di insolito' comprende
$VERSION
, il che sembra confondere instldso.sh
)
/lib/elf
a /lib
(il che non è ncessario, ma si possono aver avuto delle valide ragioni per
farlo se si è seguito lo sviluppo dell'ELF).
/etc/ld.so.conf
per aggiungere le nuove directory
/usr/i486-linuxaout/lib
(e /lib-aout
se si pensa di averne
bisogno). Poi si faccia girare /sbin/ldconfig -v
per controllare
che sono state caricate le nuove directory.
/usr/*/lib
a
/usr/i486-linuxaout/lib
. Si noti che ho scritto `librerie'
non `qualunque cosa'. Quindi si intende i file che rispondono al nome
di lib*.so*
, lib*.sa*
, o lib*.a
. Non si incominci a
spostare /usr/lib/gcc-lib
o niente di sciocco come questo in
giro.
/lib
. Si lasci intatto libc.so*
,
libm.so*
, e libdl.so*
. Se si hano link simbolici a librerie X
(libX*.so.3*
) lasciate li anche questi --- XView e qualche altro
pacchetto potrebbe averne bisogno. Si lasci ld.so*
, ld-linux.so*
e qualunque altro file che comincia con ld
. Per le librerie rimanenti,
(se ne avete qualcuna): se si ha /usr
sulla partizione root,
si mettano in /usr/i486-linuxaout/lib
. Se si ha /usr
montata separatamente, si mettano in /lib-aout
. Adesso si
faccia girare ldconfig -v
/usr/lib/ldscripts
se è li,
per la preparazione all'installazione delle utility binarie (che
la ricreeranno).
ld
e di as
(eccetto ld86
e as86
) che si può trovare in
/usr/bin
.
cpio
invece di tar
, poichè non
ha questo problema. zcat /ovunque/sia/stato/messo/libc-5.0.9.tar.gz | cpio
-iv
è l'incantesimo magico qui, che deve essere eseguito dalla
directory root.
/usr/include
e rimuovere alcune
parti.
Questa è brutta. Molti pacchetti (come ncurses) sono installati
in /usr/include
dai manutentori della distribuzione e non
sono fornite con la libreria C. Si faccia un backup dell'albero della
directory /usr/include
, si usi tar tzf
per vedere
cosa c'è nell'archivio prima di scompattarlo, poi cancellare le poche cose
di /usr/include
che sono al momento contenute. Poi si
scompatti il file libc-5.0.9.bin.tar.gz
dalla directory root.
tar -xvzf binutils-2.5.2.l17.bin.tar.gz -C /
è una buona maniera per farlo.
/usr/lib/gcc-lib/{i486-linux, i486-linuxelf, i486-linuxaout}/
Se
si usa un driver gcc
non standard, (per esempio se si usa il GNU ADA),
si copi anche quello in un posto sicuro. Poi si installi in pacchetto gcc,
di nuovo scompattando il tutto dalla directory root.
/lib/cpp
, che generalmente sotto linux è un link a
/usr/lib/gcc-lib/i486-linux/
version/cpp
. Siccome
ilpasso precedente ha cancellato qualsiasi versione a cui cpp
stava puntando, bisognerà ricreare il link:
$ cd /lib
$ ln -s /usr/lib/gcc-lib/i486-linux/2.7.0/cpp .
utmp
e wtmp
da /var/adm
a /var/run
e a /var/log
rispettivamente. Bisognerà
aggiungere alcuni link che dipendono da dove attualmente questi risiedono,
e può essere necessario creare le directory
/var/log
and /var/adm
. Io ho riprodotto qui sotto
l'output del comando ls -l
delle parti appropriate del mio sistema:
$ ls -ld /var/adm /var/log /var/run /var/log/*tmp /var/run/*tmp
lrwxrwxrwx 1 root root 3 May 24 05:53 /var/adm -> log/
drwxr-xr-x 9 root root 1024 Aug 13 23:17 /var/log/
lrwxrwxrwx 1 root root 11 Aug 13 23:17 /var/log/utmp -> ../run/utmp
-rw-r--r-- 1 root root 451472 Aug 13 23:00 /var/log/wtmp
drwxr-xr-x 2 root root 1024 Aug 13 23:17 /var/run/
-rw-r--r-- 1 root root 448 Aug 13 23:00 /var/run/utmp
Si controlli il FSSTND (dagli archivi LDP come
ftp://sunsite.unc.edu/pub/Linux/docs/fsstnd/) per la storia completa.
Fatto! Semplici test che si possono provare sono:
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/2.7.0/specs
gcc version 2.7.0
$ gcc -v -b i486-linuxaout
Reading specs from /usr/lib/gcc-lib/i486-linuxaout/2.7.0/specs
gcc version 2.7.0
$ ld -V
ld version cygnus/linux-2.5.2l.14 (with BFD cygnus/linux-2.5.2l.11)
Supported emulations:
elf_i386
i386linux
i386coff
seguiti ovviamente dal tradizionale programma ``Hello World''. Si provi
con gcc
e con gcc -b i486-linuxaout
per verificare che
sia il compilatore ELF, sia il compilatore a.out sono configurati
correttamente.
Questa è una guida deliberatamente vaga a che cosa sono i files che avete appena installato. Può essere utile per la soluzione di problemi, o per decidere cosa cancellare.
/lib
ld.so
(a.out) e ld-linux.so.1
(ELF).
Entrambe possono essere link simbolici, ma siate sicuri che i file
a cui puntano esistano.
libc.so.4
, libm.so.4
(a.out)
Questi sono link simbolici, ma curate che anche questi puntino a file
esistenti.
libc.so.5
, libm.so.5
,
libdl.so.1
, libcurses.so.1
, libtermcap.so.2
, (ELF).
Anche questi sono link simbolici.
libc.so.5.0.9
), un link simbolico
che punta allo stesso con solo il major number della versione (libc.so.5
)
ed un link simbolico che punta a quest'ultimo senza numero di versione
(libc.so
). In questa maniera:
lrwxrwxrwx 1 root root 9 May 24 05:52 libc.so -> libc.so.5
lrwxrwxrwx 1 root root 13 Aug 25 12:48 libc.so.5 -> libc.so.5.0.9
-rwxr-xr-x 1 bin bin 562683 May 19 04:47 libc.so.5.0.9
/usr/lib
libbfd.so*
,libdb.so*
, libgdbm.so*
, le librerie
condivise di ELF. Tutte consistono di tre file come spiegato in precedenza
nella sezione /lib
.
libbsd.a
, libgmon.a
, libldso.a
, libmcheck.a
,
libieee.a
, libmcheck.a
ed un lib*.a
file per ogni
libreria condivisa in ELF. Quelli che duplicano le librerie condivise
possono non essere estremamente utili per la maggioranza delle persone
--- quando si usa l'ELF si può usare lo switch gcc -g
con le
librerie condivise, così non ha più molto senso fare compilazioni statiche.
crt0.o
, gcrt0.o
. a.out, che sono i file di `inizio di
programma';uno di questi è linkato come primo file in ogni programma
di tipo a.out, a meno che non si prendano degli accorgimentio per evitarlo.
crt1.o
, crtbegin.o
, crtbeginS.o
, crtend.o
,
crtendS.o
, crti.o
, crtn.o
, gcrt1.o
. I file di startup
dell'ELF. Questi fanno una cosa simile a quanto appena visto per i
file *crt0.o
/usr/lib/ldscripts
ld
, come suggerisce
il nome stesso. Dovrebbe apparire come
$ ls /usr/lib/ldscripts/
elf_i386.x elf_i386.xs i386coff.xn i386linux.xbn
elf_i386.xbn elf_i386.xu i386coff.xr i386linux.xn
elf_i386.xn i386coff.x i386coff.xu i386linux.xr
elf_i386.xr i386coff.xbn i386linux.x i386linux.xu
/usr/i486-linux/bin
ar
, as
, gasp
, ld
, nm
, ranlib
,
strip
. Questi attualmente sono tutti link simbolici alle utility
binarie in /usr/bin
/usr/i486-linuxaout/bin
as
--- L'assembler per l'a.out, e gasp
, il suo preprocesore
delle macro
ar
, ld
, nm
, ranlib
, strip
--- link simbolici
alle utility binarie in /usr/bin
/usr/i486-linux/lib
ldscripts
è un link simbolico a /usr/lib/ldscripts
./usr/i486-linuxaout/lib
lib*.so*
. librerie condivise per a.out. Sono necesarie per
far girare programmi in formato a.out.
lib*.sa
. mozziconi di librerie per il formato a.out.
Necessarie per compilare programmi a.out. Se non si intende farlo,
si possono tranquillamente rimuoverle.
lib*.a
. librerie statiche per il formato a.out. Necessarie
per compilare programmi statici in a.out (ciaoè quando si compila con
-g
). Di nuovo, si possono rimuovere se non si ha questa intenzione.
ldscripts
è un link simbilico a /usr/lib/ldscripts
/usr/lib/gcc-lib/i486-linux/2.7.0
/usr/lib/gcc-lib/i486-linuxaout/2.7.0
... in grandi lettere amichevoli.
Avete ancora una shell in grado di girare, tuttavia, e con un pò di ingenuità
potete fare un sacco di cose con le caratteristiche intrinseche della shell.
Ricordate che echo *
è un sostituto accettabile per ls
,
e che echo >>filename
può essere usato per aggiungere linee
ad un file. Inoltre non dimenticate che ldconfig
è linkato staticamente.
Se avete spostato, ad esempio, libc.so.4
in /lib-aout
erroneamente, potete fare echo "lib-aout"
>>/etc/ld.so.conf ; ldconfig -v
ed essere di nuovo a posto.
se avete spostato /lib/ld.so
potete essere capaci di
fare sln /stupido/posto/ld.so /lib/ld.so
, se avete una copia
di ln linkata staticamente, e probabilmente vi ritroverete con tutto
a posto.
no such file or directory: /usr/bin/gcc
... quando sapete che esiste quel file. Questo solitamente
significa che il loader dinamico dell'ELF /lib/ld-linux.so.1
non è installato, o non è leggibile per qualche motivo. Dovreste
averlo installato al passo 2 in precedenza.
not a ZMAGIC file, skipping
dal comando ldconfig
. Questo è perchè avete una vecchia versione
del pacchetto ld.so, così dovete prenderne una nuova. Riguardate il passo
2dell'installazione.
bad address
tentando di far girare qualunque cosa in ELF. State usando il kernel 1.3.x, dove x<3. Fate un upgrade alla versione 1.3.3 oppure fate un downgrade a qualche versione 1.2.x
_setutent: Can't open utmp file
Questo messaggio è spesso visto in multipli di tre quando si fa partire un xterm. Andate avanti e leggete il papiro sul FSSTND verso la fine della procedura di installazione.
gcc: installation problem, cannot exec qualcosa: No such file or directory
Quando si tenta di fare una compilazione in a.out (qualcosa in
genere sono cpp
o cc1
). Può essere sia una cosa corretta,
oppure verosimilmente avete digitato
$ gcc -b -i486-linuxaout
quando avreste dovuto digitare
$ gcc -b i486-linuxaout
Notate che `i486' non inizia con un meno.