1Building older versions of GCC compatible with Linux Kernel 2.4
2===============================================================
3
4
5This document explains how to build an older supported version of the GCC
6compiler from a distribution which only offers incompatible recent versions.
7
8
9Context
10=======
11
12When Linux 2.4.0 was released in early 2001, GCC 2.95.2 was mainstream and
13GCC 2.91.66 was still widely used. The GCC development model was evolving
14and still confused. Since then, GCC has evolved a lot and stabilized. New
15versions are regularly released, and some old features from the early code
16get deprecated then removed.
17
18The kernel heavily relies on GCC's capabilities and behaviour. Some of the
19code in Linux looks strange but is in fact intended to workaround early GCC
20bugs. For these reasons, almost every new major GCC release breaks the kernel
21build process. GCC 3.4 was a real pain to introduce as it required a lot of
22rewriting in sensible areas, and GCC 4 required a lot of work, though this
23work was less complicated thanks to the cleanup efforts invested in GCC 3.4.
24
25Starting with GCC 4.2, the output code randomly fails depending on section
26ordering, which itself depends on the declaration order of functions, module
27parameters and many other things. The nasty part is that the code builds but
28randomly fails at runtime, so it is almost impossible to fix it and ensure
29that everything works, especially in the drivers area where most of the
30problems lie.
31
32As of 2008, GCC 4.3.2 is advertised as the current release and 4.2 the previous
33release. Most distributions have been shipping with 4.2 and 4.3 for some time,
34so building Linux 2.4 on a recent distribution has become a real problem for
35users who still have to support kernel 2.4 on servers, firewalls or any other
36system.
37
38
39Solution : the two-minutes process
40==================================
41
42If it is not possible to adapt the kernel to GCC, let's adapt GCC to the
43kernel. We're lucky, building GCC to build just a kernel is not hard and
44is rather fast. I call that a two-minutes process because building an
45older GCC takes about 1 minute, and the kernel with that GCC also takes
46one minute.
47
48First, you have to select which version of GCC you want to build your kernel
49with. Here are some comments on possible versions :
50
51  - 2.95.3    : very well tested for the kernel, builds kernels very fast,
52                requires a lot of patches and is rather hard to build..
53
54  - 3.0       : very buggy, avoid it.
55
56  - 3.1 & 3.2 : apparently less buggy but rarely used so bugs might have
57                remained unnoticed.
58
59  - 3.3       : used and tested for a long time. A bit slow but easy to build.
60
61  - 3.4       : was recently introduced, received less testing, though seems
62                OK. Builds kernels faster than 3.3, and is easy to build too.
63
64  - 4.0 & 4.1 : received little testing, particularly slow but may produce
65                smaller kernels when compiled with -Os.
66
67Always take the last maintenance version of a compiler (eg: 3.4.6 for 3.4).
68
69For best reliability and less hassle, I tend to recommend GCC 3.3.6. For
70improved build times (about 30% lower) and improved kernel performance, I'd
71recommend 3.4.6. It tends to produce more efficient code on i386, but has
72had a long history of causing annoyances with inline declarations. It seems
73OK though, and I build all my kernels with it. We'll assume 3.4 is used for
74the rest of this document, though what is described will work with 3.3 to
754.1 unless stated otherwise.
76
77
78Instructions
79============
80
811) Download gcc sources from the nearest mirror
82-----------------------------------------------
83
84Find a mirror address here : [ http://gcc.gnu.org/mirrors.html ] or download
85from this directory :
86
87   ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.4.6/
88
89Get gcc-core-3.4.6.tar.bz2. It only contains the C compiler, which is what you
90want.
91
922) Prepare your build environment
93---------------------------------
94
95Create a temporary directory where you'll extract the sources. Don't build on
96NFS, it may be slow. Use /tmp if you want. You'll need about 150 MB of free
97space. You'll have to extract the sources in that new directory, and create a
98temporary build directory aside it :
99
100   $ mkdir /tmp/gcc-build
101   $ cd /tmp/gcc-build
102   $ tar jxf /tmp/gcc-core-3.4.6.tar.bz2
103   $ mkdir build
104
1053) Configure gcc
106----------------
107
108You don't want your new gcc to conflict with the one already in place. I
109recommend simply prefixing it with "kernel-", and not installing it in
110/usr/bin, but rather /opt/kgcc/bin or anywhere else (/usr/local/bin will be
111used by default). I recommend choosing a place you already have in your PATH
112(such as the default /usr/local/bin), so that you don't have to pass the full
113path to the binary when building.
114
115   $ cd /tmp/gcc-build/build
116   $ ../gcc-3.4.6/configure --disable-locale --disable-shared --disable-nls \
117                            --enable-languages=c \
118                            --prefix=/opt/kgcc --program-prefix=kernel-
119
120If you're using GCC 3.3, you may see strange messages indicating that some
121programs were not found (eg: kernel-objdump). Simply ignore them.
122
123Note that you can set a lot of options, even use it as a cross-compiler. While
124very frequent, such a build will not be covered by this document.
125
1264) Build GCC
127------------
128
129Both GCC 3.3 and 3.4 support parallel building, which reduces build time on SMP
130systems :
131
132   $ make -j 4
133
134If the build fails here because of some options you added above, you'll have to
135remove the build dir and recreate it.
136
1375) Install your new GCC
138-----------------------
139
140The binaries may be a bit big, but you can strip them. Both GCC 3.3 and 3.4
141support a trick on the command line during the installation process, which
142consists in passing the "-s" flag to "install" :
143
144   $ sudo make install INSTALL_PROGRAM='${INSTALL} -s'
145
146It will be installed under the directory referred to by the "prefix" option
147above, or /usr/local/bin if none was specified :
148
149   $ ls -l /opt/kgcc/bin/kernel-gcc
150   -rwxr-xr-x  3 root root 73124 Sep  6 22:45 /opt/kgcc/bin/kernel-gcc
151
152   $ /opt/kgcc/bin/kernel-gcc -v
153   Reading specs from /tmp/gcc-3.4.6-build/tmp-inst/opt/kgcc/bin/...
154   Configured with: ../gcc-3.4.6/configure --disable-shared --disable-...
155   Thread model: posix
156   gcc version 3.4.6
157
1586) Using your new compiler
159--------------------------
160
161The compiler just has to be passed to "make" via the "CC" variable for all
162commands :
163
164  $ make CC=/opt/kgcc/bin/kernel-gcc -j 4 dep bzImage modules
165  $ sudo make CC=/opt/kgcc/bin/kernel-gcc modules_install install
166
167  or more simply, when you have it in your path :
168
169  $ make CC=kernel-gcc -j 4 dep bzImage modules
170  $ sudo make CC=kernel-gcc -j 4 modules_install install
171
172Note: make modules_install needs a 2.4-compatible depmod. If your distro is
173      2.6-based and says it does not find depmod or depmod.old, it means that
174      either modutils or module-init-tools have not been correctly installed.
175      You can still force the path to depmod by passing it in the DEPMOD
176      variable during make modules_install if you know where to find a good
177      one.
178
179
1807) I want to use a really old compiler, but compiling it breaks!
181-----------------------------------------------------------------
182
183Tackle the problem in stages. Compile 3.x.y as above. Then use that to
184compile 2.95.x (CC=/opt/kgcc/bin/kernel-gcc ./configure ...), install,
185use 2.95.x to compile the next compiler in the chain, continue as
186far as you'd like.
187
188Conclusion
189==========
190
191Building an older GCC on to build an older kernel on a newer machine is not
192really hard. It becomes harder when you have to cross-build (eg: you're
193building on a 64-bit machine for a 32-bit one). But for this, I would recommend
194that you check the excellent "crosstool" utility from Dan Kegel. It supports a
195wide variety of compilers, contains a lot of fixes and will do all the hard
196patching and configuration work for any combination you want or need.
197
198
199Suggestions and comments
200========================
201
202If you find mistakes or want to send comments about this document, please mail
203me at <w@1wt.eu>.
204
205