aboutsummaryrefslogtreecommitdiffstats
path: root/chapter06/chapter06.xml
blob: 4a168fac626e518c579088425f4a45cd80ff0c35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
<chapter id="chapter-building-system" xreflabel="Chapter 6">
<title>Installing basic system software</title>
<?dbhtml filename="chapter06.html" dir="chapter06"?>


<sect1 id="ch-system-introduction">
<title>Introduction</title>
<?dbhtml filename="introduction.html" dir="chapter06"?>

<para>In this chapter we enter the building site, and start
constructing our LFS system in earnest. That is, we chroot into
our temporary mini Linux system, create some auxiliary things,
and then start installing all the packages, one by one.</para>
 
<para>The installation of all this software is pretty straightforward,
and you will probably think it would be much shorter to give here
the generic installation instructions and explain in full only the
installation of those packages that require an alternate method.
Although we agree with that, we nevertheless choose to give the 
full instructions for each and every package, simply to minimize
the possibilities for mistakes.</para>

<para>The key to learning what makes a Linux system work is to know
what each package is used for and why the user (or the system) needs it.
For this purpose for every installed package a summary of its content is
given followed by concise descriptions of each program and library it
installed.</para>

<para>If you plan to use compiler optimizations in this chapter, take a look at
the optimization hint at <ulink url="&hints-root;optimization.txt"/>. Compiler
optimizations can make a program run slightly faster, but they may also cause
compilation difficulties and even problems when running the program. If a
package refuses to compile when using optimization, try to compile it without
optimization and see if the problem goes away. Even if the package does compile
when using optimization, there is the risk it may have been compiled incorrectly
due to complex interactions between the code and build tools. In short, the
small potential gains achieved in using compiler optimization are generally
outweighed by the risk. First time builders of LFS are encouraged to build
without custom optimizations. Your system will still be very fast and very
stable at the same time.</para>

<para>The order in which packages are installed in this chapter has
to be strictly followed, to ensure that no program gets a path referring
to <filename class="directory">/tools</filename> hard-wired into it.
For the same reason, <emphasis>do not </emphasis> compile packages
in parallel. Compiling in parallel may save you some time (especially on
dual-CPU machines), but it could result in a program containing a
hard-wired path to <filename class="directory">/tools</filename>,
which will cause the program to stop working when that directory
is removed.</para>

<para>Before the installation instructions each installation page gives some
information about the package: a concise description of what it contains, how
long it will approximately take to build it, how much disk space it needs
during this building process, the official download location of the package
(in case you just want to update a few of them), and which other packages it
needs in order to be built successfully. After the installation instructions
follows a list of programs and libraries that the package installs, together
with a series of short descriptions of these.</para>

</sect1>


<sect1 id="ch-system-proc">
<title>Mounting the proc and devpts file systems</title>
<?dbhtml filename="proc.html" dir="chapter06"?>

<para>In order for certain programs to function properly, the
<emphasis>proc</emphasis> and <emphasis>devpts</emphasis> file systems must be
available within the chroot environment. The proc file system is the process
information pseudo file system through which the kernel provides information
about the status of the system. And the devpts file system is nowadays the most
common way pseudo terminals (PTYs) are implemented. Since kernel version 2.4, a
file system can be mounted as many times and in as many places as you like,
thus it's not a problem that these file systems are already mounted on your
host system, especially so because they are virtual file systems.</para>

<para>First become <emphasis>root</emphasis>, as only <emphasis>root</emphasis>
can mount file systems in unusual places. Then check again that the LFS
environment variable is set correctly by running <userinput>echo
$LFS</userinput> and making sure it shows the path to your LFS partition's
mount point, which is <filename class="directory">/mnt/lfs</filename> if you
followed our example.</para>

<para>Now make the mount points for these filesystems:</para>

<screen><userinput>mkdir -p $LFS/{proc,dev/pts}</userinput></screen>

<para>Mount the <emphasis>proc</emphasis> file system with:</para>

<screen><userinput>mount proc $LFS/proc -t proc</userinput></screen>

<para>And mount the <emphasis>devpts</emphasis> file system with:</para>

<screen><userinput>mount devpts $LFS/dev/pts -t devpts</userinput></screen>

<para>This last command might fail with an error like:</para>

<blockquote><screen>filesystem devpts not supported by kernel</screen></blockquote>

<para>The most likely cause for this is that your host system's kernel was
compiled without support for the devpts file system (you can check which file
systems your kernel supports with <command>cat /proc/filesystems</command>,
for example). A few PTYs are needed to be able to run the suites for Binutils
and GCC later on. If your kernel does not support devpts, do not worry, there
is another way to get them working inside the chroot environment. We'll cover
this shortly in the <xref linkend="ch-system-MAKEDEV"/> section.</para>

<para>Remember that if for any reason you stop working on your LFS, and start
again later, it's important to check that these file systems are mounted again
before entering the chroot environment, otherwise problems could occur.</para>

</sect1>


<sect1 id="ch-system-chroot">
<title>Entering the chroot environment</title>
<?dbhtml filename="chroot.html" dir="chapter06"?>

<para>It is time to enter the chroot environment in order to begin building
and installing your final LFS system. Still as <emphasis>root</emphasis> run
the following command to enter the small world that is, at the moment,
populated with only the temporary tools:</para>

<screen><userinput>chroot $LFS /tools/bin/env -i \
&nbsp;&nbsp;&nbsp;&nbsp;HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
&nbsp;&nbsp;&nbsp;&nbsp;PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin \
&nbsp;&nbsp;&nbsp;&nbsp;/tools/bin/bash --login +h</userinput></screen>

<para>The <emphasis>-i</emphasis> option given to the
<command>env</command> command will clear all variables of the chroot
environment. After that, only the HOME, TERM, PS1 and PATH variables are
set again. The TERM=$TERM construct will set the TERM variable inside chroot
to the same value as outside chroot; this variable is needed for programs
like <command>vim</command> and <command>less</command> to operate
properly. If you need other variables present, such as CFLAGS or CXXFLAGS,
this is a good place to set them again.</para>

<para>From this point on there's no need to use the LFS variable anymore,
because everything you do will be restricted to the LFS file system -- since
what the shell thinks is <filename class="directory">/</filename> is actually
the value of <filename class="directory">$LFS</filename>, which was passed to
the chroot command.</para>

<para>Notice that <filename class="directory">/tools/bin</filename> comes
last in the PATH. This means that a temporary tool will not be used any more
as soon as its final version is installed. Well, at least when the shell
doesn't remember the locations of executed binaries -- for this reason hashing
is switched off by passing the <emphasis>+h</emphasis> option to
<command>bash</command>.</para>

<para>You have to make sure all the commands in the rest of this chapter and
in the following chapters are run from within the chroot environment.
If you ever leave this environment for any reason (rebooting for example),
you must remember to first mount the proc and devpts file systems (discussed
in the previous section) <emphasis>and</emphasis> enter chroot again before
continuing with the installations.</para>

<para>Note that the bash prompt will say "I have no name!" This is normal, as
the <filename>/etc/passwd</filename> file has not been created yet.</para>

</sect1>


<sect1 id="ch-system-changingowner">
<title>Changing ownership</title>
<?dbhtml filename="changingowner.html" dir="chapter06"?>

<para>Right now the <filename class="directory">/tools</filename> directory
is owned by the user <emphasis>lfs</emphasis>, a user that exists only on your
host system. Although you will probably want to delete the
<filename class="directory">/tools</filename> directory once you have
finished your LFS system, you may want to keep it around, for example to
build more LFS systems. But if you keep the
<filename class="directory">/tools</filename> directory as it is, you end up
with files owned by a user ID without a corresponding account. This is
dangerous because a user account created later on could get this same user ID
and would suddenly own the <filename class="directory">/tools</filename>
directory and all the files therein, thus exposing these files to possible
malicious manipulation.</para>

<para>To avoid this issue, you could add the <emphasis>lfs</emphasis> user to
your new LFS system later on when creating the <filename>/etc/passwd</filename>
file, taking care to assign it the same user and group IDs as on your host
system. Alternatively, you can (and the book assumes you do) assign the
contents of the <filename class="directory">/tools</filename> directory to
user <emphasis>root</emphasis> by running the following command:</para>

<screen><userinput>chown -R 0:0 /tools</userinput></screen>

<para>The command uses "0:0" instead of "root:root", because
<userinput>chown</userinput> is unable to resolve the name "root" until the
password file has been created.</para>

</sect1>


<sect1 id="ch-system-creatingdirs">
<title>Creating directories</title>
<?dbhtml filename="creatingdirs.html" dir="chapter06"?>

<para>Let's now create some structure in our LFS file system. Let's create
a directory tree. Issuing the following commands will create a more or less
standard tree:</para>
 
<screen><userinput>mkdir -p /{bin,boot,dev/{pts,shm},etc/opt,home,lib,mnt,proc}
mkdir -p /{root,sbin,tmp,usr/local,var,opt}
for dirname in /usr /usr/local
&nbsp;&nbsp;&nbsp;&nbsp;do
&nbsp;&nbsp;&nbsp;&nbsp;mkdir $dirname/{bin,etc,include,lib,sbin,share,src}
&nbsp;&nbsp;&nbsp;&nbsp;ln -s share/{man,doc,info} $dirname
&nbsp;&nbsp;&nbsp;&nbsp;mkdir $dirname/share/{doc,info,locale,man}
&nbsp;&nbsp;&nbsp;&nbsp;mkdir $dirname/share/{misc,terminfo,zoneinfo}
&nbsp;&nbsp;&nbsp;&nbsp;mkdir $dirname/share/man/man{1,2,3,4,5,6,7,8}
done
mkdir /var/{lock,log,mail,run,spool}
mkdir -p /var/{tmp,opt,cache,lib/misc,local}
mkdir /opt/{bin,doc,include,info}
mkdir -p /opt/{lib,man/man{1,2,3,4,5,6,7,8}}</userinput></screen>

<para>Directories are, by default, created with permission mode 755, but this
isn't desirable for all directories. We will make two changes: one to the home
directory of <emphasis>root</emphasis>, and another to the directories for
temporary files.</para>

<screen><userinput>chmod 0750 /root
chmod 1777 /tmp /var/tmp</userinput></screen>

<para>The first mode change ensures that not just anybody can enter the
<filename class="directory">/root</filename> directory -- the same
as a normal user would do with his or her home directory.
The second mode change makes sure that any user can write to the
<filename class="directory">/tmp</filename> and
<filename class="directory">/var/tmp</filename> directories, but
cannot remove other users' files from them. The latter is prohibited
by the so-called "sticky bit" -- the highest bit in the 1777 bit mask.</para>

<sect2>
<title>FHS compliance note</title>

<para>We have based our directory tree on the FHS standard (available at
<ulink url="http://www.pathname.com/fhs/"/>). Besides the above created
tree this standard stipulates the existence of
<filename class="directory">/usr/local/games</filename> and
<filename class="directory">/usr/share/games</filename>, but we don't
much like these for a base system. However, feel free to make your system
FHS-compliant. As to the structure of the
<filename class="directory">/usr/local/share</filename> subdirectory, the FHS
isn't precise, so we created here the directories that we think are needed.</para>

</sect2>

</sect1>


<sect1 id="ch-system-createfiles">
<title>Creating essential symlinks</title>
<?dbhtml filename="createfiles.html" dir="chapter06"?>

<para>Some programs hard-wire paths to programs which don't exist yet. In
order to satisfy these programs, we create a number of symbolic links which
will be replaced by real files throughout the course of this chapter when
we're installing all the software.</para>

<screen><userinput>ln -s /tools/bin/{bash,cat,pwd,stty} /bin
ln -s /tools/bin/perl /usr/bin
ln -s /tools/lib/libgcc_s.so.1 /usr/lib
ln -s bash /bin/sh</userinput></screen>

</sect1>


<sect1 id="ch-system-pwdgroup">
<title>Creating the passwd, group and log files</title>
<?dbhtml filename="pwdgroup.html" dir="chapter06"?>

<para>In order for <emphasis>root</emphasis> to be able to login and for the 
name "root" to be recognized, there need to be relevant entries in the 
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> files.</para>

<para>Create the <filename>/etc/passwd</filename> file by running the following 
command:</para>

<screen><userinput>cat &gt; /etc/passwd &lt;&lt; "EOF"</userinput>
root:x:0:0:root:/root:/bin/bash
<userinput>EOF</userinput></screen>

<para>The actual password for <emphasis>root</emphasis> (the "x" here is just a 
placeholder) will be set later.</para>

<para>Create the <filename>/etc/group</filename> file by running the following 
command:</para>

<screen><userinput>cat &gt; /etc/group &lt;&lt; "EOF"</userinput>
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
<userinput>EOF</userinput></screen>

<para>The created groups aren't part of any standard -- they are some of the
groups that the <command>make_devices</command> script in the next section
uses. The LSB (<ulink url="http://www.linuxbase.org/">Linux Standard
Base</ulink>) recommends only that, beside the group "root" with a GID of 0, a
group "bin" with a GID of 1 be present. All other group names and GIDs can
be chosen freely by the system administrator, since well-written packages don't
depend on GID numbers but use the group's name.</para>

<para>To get rid of the "I have no name!" prompt, we will start a new shell.
Since we installed a full Glibc in <xref linkend="chapter-temporary-tools"/>,
and have just created the <filename>/etc/passwd</filename> and
<filename>/etc/group</filename> files, user name and group name resolution
will now work.</para>

<screen><userinput>exec /tools/bin/bash --login +h</userinput></screen>

<para>Note the use of the <emphasis>+h</emphasis> directive. This tells
<command>bash</command> not to use its internal path hashing. Without this
directive, <command>bash</command> would remember the paths to binaries it
has executed. Since we want to use our newly compiled binaries as soon as
they are installed, we turn off this function for the duration of this
chapter.</para>

<para>The <command>login</command>, <command>agetty</command> and
<command>init</command> programs (and some others) use a number of log
files to record information such as who was logged into the system and when.
These programs, however, won't write to the log files if they don't already
exist. Initialize the log files and give them their proper permissions:</para>

<screen><userinput>touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chmod 644 /var/run/utmp /var/log/{btmp,lastlog,wtmp}</userinput></screen>

<para>The <filename>/var/run/utmp</filename> file records the users that are
currently logged in. The <filename>/var/log/wtmp</filename> file records all
logins and logouts. The <filename>/var/log/lastlog</filename> file records for
each user when he or she last logged in. The <filename>/var/log/btmp</filename>
file records the bad login attempts.</para>

</sect1>


&c6-makedev;
&c6-kernel-headers;
&c6-manpages;
&c6-glibc;


<sect1 id="ch-system-readjusting">
<title>Re-adjusting the toolchain</title>
<?dbhtml filename="readjusting.html" dir="chapter06"?>

<para>Now that the new and final C libraries have been installed, it's time to
adjust our toolchain again. We'll adjust it so that it will link any newly
compiled program against these new libraries. This is in fact the same we did
in the "Adjusting" phase in the beginning of the previous chapter, even though
it looks like the reverse: then we guided the chain from the host's
<filename class="directory">{,/usr}/lib</filename> to the new
<filename class="directory">/tools/lib</filename>, now we guide it from that
same <filename class="directory">/tools/lib</filename>
to the LFS's <filename class="directory">{,/usr}/lib</filename>.</para>

<para>First we adjust the linker. For this we retained the
source and build directories from the second pass over Binutils. Install the
adjusted linker by running the following from within the
<filename class="directory">binutils-build</filename> directory:</para>

<screen><userinput>make -C ld INSTALL=/tools/bin/install install</userinput></screen>

<note><para>If you somehow missed the earlier warning to retain the Binutils
source and build directories from the second pass in
<xref linkend="chapter-temporary-tools"/>, or otherwise accidentally deleted them or just
don't have access to them, don't worry, all is not lost. Just ignore the above
command. The result will be that the next package, Binutils, will link against
the C libraries in <filename class="directory">/tools</filename> rather
than <filename class="directory">{,/usr}/lib</filename>. This is not ideal,
however, our testing has shown that the resulting Binutils program binaries
should be identical.</para></note>

<para>From now on every compiled program will link <emphasis>only</emphasis>
against the libraries in <filename>/usr/lib</filename> and
<filename>/lib</filename>. The extra
<emphasis>INSTALL=/tools/bin/install</emphasis> is needed because the Makefile
created during the second pass still contains the reference to
<filename>/usr/bin/install</filename>, which we obviously haven't installed yet.
Some host distributions contain a <filename class="symlink">ginstall</filename>
symbolic link which takes precedence in the Makefile and thus can cause a
problem here. The above command takes care of this also.</para>

<para>You can now remove the Binutils source and build directories.</para>

<para>The next thing to do is to amend our GCC specs file so that it points
to the new dynamic linker. Just like earlier on, we use a sed to accomplish
this:</para>

<!-- Ampersands are needed to allow cut and paste -->

<screen><userinput>SPECFILE=/tools/lib/gcc-lib/*/*/specs &amp;&amp;
sed -e 's@ /tools/lib/ld-linux.so.2@ /lib/ld-linux.so.2@g' \
&nbsp;&nbsp;&nbsp;&nbsp;$SPECFILE &gt; newspecfile &amp;&amp;
mv -f newspecfile $SPECFILE &amp;&amp;
unset SPECFILE</userinput></screen>

<para>Again, cutting and pasting the above is recommended. And just like
before, it is a good idea to visually inspect the specs file to verify the
intended change was actually made.</para>

<important><para>If you are working on a platform where the name of the dynamic
linker is something other than <filename>ld-linux.so.2</filename>, you
<emphasis>must</emphasis> substitute <filename>ld-linux.so.2</filename> with the
name of your platform's dynamic linker in the above commands. Refer back to
<xref linkend="ch-tools-toolchaintechnotes"/> if necessary.</para></important>

<!-- HACK - Force some whitespace to appease tidy -->
<literallayout></literallayout>

<caution><para>It is imperative at this point to stop and ensure that the
basic functions (compiling and linking) of the adjusted toolchain are working
as expected. For this we are going to perform a simple sanity check:</para>

<screen><userinput>echo 'main(){}' &gt; dummy.c
cc dummy.c
readelf -l a.out | grep ': /lib'</userinput></screen>

<para>If everything is working correctly, there should be no errors, and the
output of the last command will be:</para>

<blockquote><screen>[Requesting program interpreter: /lib/ld-linux.so.2]</screen></blockquote>

<para>(Of course allowing for platform specific differences in dynamic linker
name). Note especially that <filename class="directory">/lib</filename> now
appears as the prefix of our dynamic linker. If you did not receive the output
as shown above, or received no output at all, then something is seriously wrong.
You will need to investigate and retrace your steps to find out where the
problem is and correct it. There is no point in continuing until this is done.
Most likely something went wrong with the specs file amendment above.</para>

<para>Once you are satisfied that all is well, clean up the test files:</para>

<screen><userinput>rm dummy.c a.out</userinput></screen>
</caution>

<!-- HACK - Force some whitespace to appease tidy -->
<literallayout></literallayout>

</sect1>


&c6-binutils;
&c6-gcc;

&c6-coreutils;
&c6-zlib;
&c6-lfs-utils;
&c6-findutils;
&c6-gawk;
&c6-ncurses;
&c6-vim;
&c6-m4;
&c6-bison;
&c6-less;
&c6-groff;
&c6-sed;
&c6-flex;
&c6-gettext;
&c6-nettools;
&c6-inetutils;
&c6-perl;
&c6-texinfo;
&c6-autoconf;
&c6-automake;
&c6-bash;
&c6-file;
&c6-libtool;
&c6-bzip2;
&c6-diffutils;
&c6-ed;
&c6-kbd;
&c6-e2fsprogs;
&c6-grep;
&c6-grub;
&c6-gzip;
&c6-man;
&c6-make;
&c6-modutils;
&c6-patch;
&c6-procinfo;
&c6-procps;
&c6-psmisc;
&c6-shadow;
&c6-sysklogd;
&c6-sysvinit;
&c6-tar;
&c6-utillinux;
&c6-gcc-2953;


<sect1 id="ch-system-revisedchroot">
<title>Revised chroot command</title>
<?dbhtml filename="revisedchroot.html" dir="chapter06"?>

<para>From now on when you exit the chroot environment and wish to re-enter
it, you should run the following modified chroot command:</para>

<screen><userinput>chroot $LFS /usr/bin/env -i \
&nbsp;&nbsp;&nbsp;&nbsp;HOME=/root TERM=$TERM PS1='\u:\w\$ ' \
&nbsp;&nbsp;&nbsp;&nbsp;PATH=/bin:/usr/bin:/sbin:/usr/sbin \
&nbsp;&nbsp;&nbsp;&nbsp;/bin/bash --login</userinput></screen>

<para>The reason being there is no longer any need to use programs from the
<filename class="directory">/tools</filename> directory. However, we don't
want to remove the <filename class="directory">/tools</filename> directory
just yet. There is still some use for it towards the end of the book.</para>

</sect1>


&c6-aboutdebug;

</chapter>