LDP/LDP/guide/docbook/Pocket-Linux-Guide/phase2.xml

267 lines
11 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<chapter id="phase2">
<title>Saving Space</title>
<sect1>
<title>Analysis</title>
<para>One of the drawbacks in the prototype phase of the project was that
the diskset was not all that useful. The only commands that worked were
the ones built into the BASH shell. We could improve our root disk by
installing commands like <command>cat</command>, <command>ls</command>,
<command>mv</command>, <command>rm</command> and so on. Unfortunately, we
are short on space. The current root disk has no shared libraries so each
utility would have to be statically-linked just like the BASH shell. A lot
of big binaries together with a static shell will rapidly exceed the tiny
1.44M of available disk space. So our main goal in this phase should be to
maximize space savings on the root disk and pave the way for expanded
functionality in the next phase.</para>
</sect1>
<sect1>
<title>Design</title>
<para>Take another look at the Bootdisk-HOWTO and notice how many
utilities can be squeezed onto a 1.44M floppy. There are three things that
make this possible. One is the use of shared libraries. The second is
stripped binaries. And the third is the use of a compressed filesystem. We
can use all of these techniques to save space on our root disk.</para>
<sect2>
<title>Shared Libraries</title>
<para>First, in order to use shared libraries we will need to rebuild
the BASH shell. This time we will configure it without using the
<option>--enable-static-link</option> option. Once BASH is rebuilt we
need to figure out which libraries it is linked with and be sure to
include them on the root disk. The <command>ldd</command> command makes
this job easy. By typing <command>ldd bash</command> on the command-line
we can see a list of all the shared libraries that BASH uses. As long as
all these libraries are copied to the root disk, the new BASH build
should work fine.</para>
</sect2>
<sect2>
<title>Stripped Binaries</title>
<para>Next, we should strip any binaries that get copied to the root
disk. The manpage for <command>strip</command> does not give much
description of what it does other than to say, "strip discards all
symbols from the object files." It seems like removing pieces of a
binary would render it useless, but this is not the case. The reason it
works is because a large number of these discarded symbols are used for
debugging. While debugging symbols are very helpful to programmers
working to improve the code, they do not do much for the average
end-user other than take up more disk space. And since space is at a
premium, we should definitely remove as many symbols as possible from
BASH and any other binaries before we copy over them to the
ramdisk.</para>
<para>The process of stripping files to save space also works with
shared library files. But when stripping libraries it is important to
use the <option>--strip-unneeded</option> option so as not to break
them. Using <option>--strip-unneeded</option> shrinks the file size, but
leaves the symbols needed for relocation intact which is something that
shared libraries need to function properly.</para>
</sect2>
<sect2>
<title>Compressed Root Filesystem</title>
<para>Finally, we can tackle the problem of how to build a compressed
root filesystem. The Bootdisk-HOWTO suggests three ways of constructing
a compressed root filesystem using either a ramdisk, a spare hard drive
partition or a loopback device. This project will concentrate on using
the ramdisk approach. It seems logical that if the root filesystem is
going to be run from a ramdisk, it may as well be built on a ramdisk.
All we have to do is create a second extended filesystem on a ramdisk
device, mount it and copy files to it. Once the filesystem is populated
with all the files that the root disk needs, we simply unmount it,
compress it and write it out to floppy.</para>
<note>
<para>For this to work, we need to make sure the system used for
building has ramdisk support. If ramdisk is not available it is also
possible to use a loopback device. See the Bootdisk-HOWTO for more
information on using loopback devices.</para>
</note>
</sect2>
</sect1>
<sect1>
<title>Construction</title>
<para>This section is written using ramdisk seven
(<filename>/dev/ram7</filename>) to build the root image. There is nothing
particularly special about ramdisk seven and it is possible to use any of
the other available ramdisks provided they are not already in use.</para>
<sect2>
<title>Create a ramdisk</title>
<para><programlisting><prompt>bash#</prompt> dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
<prompt>bash#</prompt> mke2fs -m0 /dev/ram7 4096
<prompt>bash#</prompt> mount /dev/ram7 /mnt</programlisting></para>
</sect2>
<sect2>
<title>Rebuild the BASH shell</title>
<para><programlisting><prompt>bash#</prompt> cd /usr/src/bash-3.0
<prompt>bash#</prompt> make distclean
<prompt>bash#</prompt> export CC="gcc -mcpu=i386"
<prompt>bash#</prompt> ./configure --enable-minimal-config --host=i386-pc-linux-gnu
<prompt>bash#</prompt> make
<prompt>bash#</prompt> strip bash</programlisting></para>
</sect2>
<sect2>
<title>Determine which libraries are required</title>
<para><programlisting><prompt>bash#</prompt> ldd bash</programlisting></para>
<para>View the output from the <command>ldd</command> command. It should
look similar to the example below.</para>
<screen>bash# ldd bash
libdl.so.2 =&gt; /lib/libdl.so.2 (0x4001d000)
libc.so.6 =&gt; /lib/libc.so.6 (0x40020000)
/lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x40000000)</screen>
<note>
<para>Some systems may have a slightly different library set up. For
example, you may see <computeroutput>libc.so.6 =&gt;
/lib/tls/libc.so.6</computeroutput> rather than
<computeroutput>libc.so.6 =&gt; /lib/libc.so.6</computeroutput> as
shown in the example. If your <command>ldd</command> output does not
match the example then use the path given by your
<command>ldd</command> command when completing the next step.</para>
</note>
</sect2>
<sect2>
<title>Copy BASH and its libraries to the ramdisk</title>
<para><programlisting><prompt>bash#</prompt> mkdir /mnt/bin
<prompt>bash#</prompt> cp bash /mnt/bin
<prompt>bash#</prompt> ln -s bash /mnt/bin/sh
<prompt>bash#</prompt> mkdir /mnt/lib
<prompt>bash#</prompt> strip --strip-unneeded -o /mnt/lib/libdl.so.2 /lib/libdl.so.2
<prompt>bash#</prompt> strip --strip-unneeded -o /mnt/lib/libc.so.6 /lib/libc.so.6
<prompt>bash#</prompt> strip --strip-unneeded -o /mnt/lib/ld-linux.so.2 /lib/ld-linux.so.2
<prompt>bash#</prompt> chmod +x /mnt/lib/ld-linux.so.2</programlisting><note>
<para>Using <command>strip -o</command> might seem an odd way to
copy library files from the development system to the ramdisk. What
it does is strip the symbols while the file is in transit from the
source location to the destination. This has the effect of stripping
symbols from the library on the ramdisk without altering the
libraries on the development system. Unfortunately file permissions
are lost when copying libraries this way which is why the
<command>chmod +x</command> command is then used to set the execute
flag for the rootdisk's dynamic loader.</para>
</note></para>
</sect2>
<sect2>
<title>Create a console device</title>
<para><programlisting><prompt>bash#</prompt> mkdir /mnt/dev
<prompt>bash#</prompt> mknod /mnt/dev/console c 5 1</programlisting></para>
</sect2>
<sect2>
<title>Compress the ramdisk image</title>
<para><programlisting><prompt>bash#</prompt> cd /
<prompt>bash#</prompt> umount /dev/ram7
<prompt>bash#</prompt> dd if=/dev/ram7 of=~/phase2-image bs=1k count=4096
<prompt>bash#</prompt> gzip -9 ~/phase2-image</programlisting></para>
</sect2>
<sect2>
<title>Copy the compressed image to diskette</title>
<para>Insert the floppy labeled "root disk" into drive fd0.</para>
<para><programlisting><prompt>bash#</prompt> dd if=~/phase2-image.gz of=/dev/fd0 bs=1k</programlisting></para>
</sect2>
</sect1>
<sect1>
<title>Implementation</title>
<para>Successful implementation of this phase is probably the most
difficult part of the Pocket Linux Guide. If you need help getting things
to work please visit the <ulink
url="http://pocket-linux.sourceforge.net">Pocket Linux Guide Resource
Site</ulink> to browse the troubleshooting forum and subscribe to the
mailing list.</para>
<sect2>
<title>System startup</title>
<para>Follow these steps to boot:</para>
<itemizedlist>
<listitem>
<para>Restart the PC using the boot disk from the previous
chapter.</para>
</listitem>
<listitem>
<para>At the <prompt>grub&gt;</prompt> prompt, type
<userinput>kernel (fd0)/boot/vmlinuz init=/bin/sh root=/dev/fd0
load_ramdisk=1 prompt_ramdisk=1</userinput> and press
<keycap>Enter</keycap>.</para>
</listitem>
<listitem>
<para>Type <userinput>boot</userinput> at the
<prompt>grub&gt;</prompt> prompt and press
<keycap>Enter</keycap>.</para>
</listitem>
<listitem>
<para>Insert the new, compressed root disk when prompted.</para>
</listitem>
</itemizedlist>
<para>The screen output should be similar to the following
example:</para>
<para><screen>GNU GRUB version 0.95
grub&gt; kernel (fd0)/boot/vmlinuz init=/bin/sh root=/dev/fd0 load_ramdisk=1 prompt_ramdisk=1
[Linux-bzImage, setup=0xc00, size=0xce29b]
grub&gt; boot
Linux version 2.4.26
..
.. [various kernel messages]
..
VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 178k freed
# _</screen></para>
</sect2>
<sect2>
<title>Verify results</title>
<para>If the implementation was successful, this new root disk should
behave exactly like the root disk from the previous chapter. The key
difference is that this compressed root disk has much more room to grow
and we will put this extra space to good use in the next phase of the
project.</para>
</sect2>
<sect2>
<title>System shutdown</title>
<para>Remove the diskette from fd0 and restart the system using
<keycap>CTRL</keycap>-<keycap>ALT</keycap>-<keycap>DELETE</keycap>.</para>
</sect2>
</sect1>
</chapter>