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

411 lines
14 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<chapter id="phase1">
<title>A Simple Prototype</title>
<sect1>
<title>Analysis</title>
<para>Since this is the first phase of the project it will be kept very
simple. The goal here is not to create the ultimate GNU/Linux system on
the first try. Instead, we will be building a very minimal, working system
to be used as a building block in subsequent phases of the project.
Keeping this in mind, we can list a few goals for phase one.</para>
<itemizedlist>
<listitem>
<para>Keep it simple to avoid stressing out.</para>
</listitem>
<listitem>
<para>Build something that works for instant gratification.</para>
</listitem>
<listitem>
<para>Make something that it is useful in later phases of the
project.</para>
</listitem>
</itemizedlist>
</sect1>
<sect1>
<title>Design</title>
<sect2>
<title>Simplification</title>
<para>Take a moment to skim through the Bootdisk-HOWTO or the
From-PowerUp-to-BASH-Prompt-HOWTO. These HOWTO documents can be found
online at <ulink
url="http://www.tldp.org/docs.html#howto">http://www.tldp.org/docs.html#howto</ulink>.
Both documents offer an excellent view of what it takes to get a
GNU/Linux system up and running. There is also a lot of information to
digest. Remember that one of our goals is, "keep it simple to avoid
stressing out," so we want to ignore everything but the absolutely
critical pieces of a boot / root diskset.</para>
<para>Basically it boils down to the following required items:</para>
<itemizedlist>
<listitem>
<para>A boot loader</para>
</listitem>
<listitem>
<para>The Linux kernel</para>
</listitem>
<listitem>
<para>A shell</para>
</listitem>
<listitem>
<para>Some <filename>/dev</filename> files</para>
</listitem>
</itemizedlist>
<para>We don't even need an init daemon. The kernel can be told to run
the shell directly by passing it an option through the boot
loader.</para>
<para>For easy construction we will build a two-disk boot / root set
rather than trying to get everything onto a single diskette. The boot
loader and kernel will go on the boot disk and the shell will reside on
the root disk.</para>
</sect2>
<sect2>
<title>Boot Disk</title>
<para>For the boot disk we simply need to install the GRUB bootloader
and a Linux kernel. We will need to use a kernel that does not require
modules for the hardware we need to access. Mainly, it should have
compiled-in support for the floppy drive, ram disk, second extended
filesystem, proc filesystem, ELF binaries, and a text-based console. If
such a kernel is not available, it will need to be built from source
code. Kwan Lowe's <ulink
url="http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html">Kernel
Rebuild Guide</ulink> is a good reference for this task, however we can
ignore the sections that deal with modules and the initial
ramdisk.</para>
</sect2>
<sect2>
<title>Root Disk</title>
<para>For the root disk we will need a floppy that has been prepared
with a filesystem. We will also need a BASH shell that is
statically-linked so we can avoid the additional complexities of shared
libraries. The <command>configure</command> program in the BASH source
code recognizes the <option>--enable-static-link</option> option for
this feature. We will also be using the
<option>--enable-minimal-config</option> option to keep the BASH binary
down to a manageable size. Additional requirements for the root disk are
a <filename>/dev</filename> directory and a device file for the console.
The <filename>console</filename> device is required for BASH to be able
to communicate with the keyboard and video display.</para>
</sect2>
<sect2>
<title>CPU Compatibility</title>
<para>There is one other, less obvious requirement to keep in mind and
that is CPU compatibility. Each generation of CPU features a more
complex architecture than its predecessor. Late generation chips have
additional registers and instructions when compared to an older 486 or
386. So a kernel optimized for a new, fast 6x86 machine will not run on
an older box. (See the <filename>README</filename> file in the Linux
kernel source code for details.) A BASH shell built for a 6x86 will
probably not run on an older processor either. To avoid this problem, we
can choose the 386 as a lowest common denominator CPU and build all the
code for that architecture.</para>
</sect2>
</sect1>
<sect1>
<title>Construction</title>
<para>In this section, we will be building the actual boot disk and root
disk floppies. Lines preceded by <prompt>bash#</prompt> indicate a shell
command and lines starting with <prompt>grub&gt;</prompt> indicate a
command typed within the grub shell.</para>
<sect2>
<title>Prepare the boot disk media</title>
<para>Insert a blank diskette labeled "boot disk".</para>
<note>
<para>It may be necessary to erase the "blank" diskette if it comes
factory pre-formatted for another, non-Linux operating system. This
can be done using the command <command>dd if=/dev/zero of=/dev/fd0
bs=1k count=1440</command></para>
</note>
<para><programlisting><prompt>bash#</prompt> mke2fs -m0 /dev/fd0
<prompt>bash#</prompt> mount /dev/fd0 /mnt</programlisting></para>
</sect2>
<sect2>
<title>Build the GRUB bootloader</title>
<para>Get the GRUB source code from <ulink
url="ftp://alpha.gnu.org/gnu/grub/">ftp://alpha.gnu.org/gnu/grub/</ulink>
and unpack it into the <filename>/usr/src</filename> directory.</para>
<para>Configure and build the GRUB source code for an i386 processor by
using the following commands:</para>
<programlisting>bash# cd /usr/src/grub-0.95
bash# export CC="gcc -mcpu=i386"
bash# ./configure --host=i386-pc-linux-gnu --without-curses
bash# make</programlisting>
</sect2>
<sect2>
<title>Copy the bootloader files to diskette</title>
<para>Normally, after compiling source code, one would use the command
<command>make install</command> to copy the finished files to their
proper destinations in the filesystem. However, using <command>make
install</command> does not work well with small media like the floppy
disks we are using. The problem is that there are many files in a
package besides the actual binaries that get the job done. For example,
there are often man or info pages that provide documentation. These
extra files can take up more space than we can spare on the diskette. We
can work around this limitation by copying essential files manually
rather than using <command>make install</command>.</para>
<para>For GRUB to boot we will need to copy the stage1 and stage2
bootloader files to the <filename>/boot/grub</filename> directory on the
boot floppy.</para>
<programlisting><prompt>bash#</prompt> mkdir -p /mnt/boot/grub
<prompt>bash#</prompt> cp /usr/src/grub-0.95/stage1/stage1 /mnt/boot/grub
<prompt>bash#</prompt> cp /usr/src/grub-0.95/stage2/stage2 /mnt/boot/grub</programlisting>
</sect2>
<sect2>
<title>Finish bootloader installation</title>
<para>Once the bootloader's files are copied to the boot disk we can
enter the grub shell to finish the installation.</para>
<programlisting><prompt>bash#</prompt> /usr/src/grub-0.95/grub/grub
<prompt>grub&gt;</prompt> root (fd0)
<prompt>grub&gt;</prompt> setup (fd0)
<prompt>grub&gt;</prompt> quit</programlisting>
</sect2>
<sect2>
<title>Build the Linux kernel</title>
<para>The steps for building the kernel were tested using Linux kernel
version 2.4.26 and should work any 2.4.x or 2.6.x kernel. The latest
version of the kernel source code may be downloaded from <ulink
url="http://www.kernel.org/">http://www.kernel.org/</ulink> or one of
its mirrors.</para>
<note>
<para>The instructions below are very brief and are intended for
someone who has previous experience building custom kernels. A more
detailed explanation of the kernel building process can be found in
the <ulink
url="http://www.digitalhermit.com/linux/Kernel-Build-HOWTO.html">Kernel
Rebuild Guide</ulink> by Kwan Lowe.</para>
</note>
<para><programlisting><prompt>bash#</prompt> cd /usr/src/linux
<prompt>bash#</prompt> make menuconfig</programlisting></para>
<para>Be sure to configure support for the following:</para>
<itemizedlist>
<listitem>
<para>386 processor</para>
</listitem>
<listitem>
<para>Console on virtual terminal (2.4.x kernels only)</para>
</listitem>
<listitem>
<para>ELF binaries</para>
</listitem>
<listitem>
<para>Floppy disk</para>
</listitem>
<listitem>
<para>proc filesystem</para>
</listitem>
<listitem>
<para>RAM disk with a default size of 4096K</para>
</listitem>
<listitem>
<para>Second extended (ext2) filesystem</para>
</listitem>
<listitem>
<para>VGA console</para>
</listitem>
</itemizedlist>
<para><programlisting><prompt>bash#</prompt> make dep
<prompt>bash#</prompt> make clean
<prompt>bash#</prompt> make bzImage</programlisting></para>
</sect2>
<sect2>
<title>Copy the kernel to diskette</title>
<para><programlisting><prompt>bash#</prompt> cp /usr/src/linux/arch/i386/boot/bzImage /mnt/boot/vmlinuz</programlisting></para>
</sect2>
<sect2>
<title>Unmount the boot disk</title>
<para><programlisting><prompt>bash#</prompt> cd /
<prompt>bash#</prompt> umount /mnt</programlisting></para>
</sect2>
<sect2>
<title>Prepare the root disk media</title>
<para>Insert a blank diskette labeled "root disk".</para>
<para><programlisting><prompt>bash#</prompt> mke2fs -m0 /dev/fd0
<prompt>bash#</prompt> mount /dev/fd0 /mnt</programlisting></para>
</sect2>
<sect2>
<title>Build BASH</title>
<para>Get the bash-3.0 source code package from <ulink
url="ftp://ftp.gnu.org/gnu/bash/">ftp://ftp.gnu.org/gnu/bash/</ulink>
and untar it into the <filename>/usr/src</filename> directory.</para>
<para>Build BASH for an i386 CPU with the following commands:</para>
<para><programlisting><prompt>bash#</prompt> cd /usr/src/bash-3.0
<prompt>bash#</prompt> export CC="gcc -mcpu=i386"
<prompt>bash#</prompt> ./configure --enable-static-link \
--enable-minimal-config --host=i386-pc-linux-gnu
<prompt>bash#</prompt> make
<prompt>bash#</prompt> strip bash</programlisting></para>
</sect2>
<sect2>
<title>Copy BASH to the root disk</title>
<para><programlisting><prompt>bash#</prompt> mkdir /mnt/bin
<prompt>bash#</prompt> cp bash /mnt/bin/bash
<prompt>bash#</prompt> ln -s bash /mnt/bin/sh</programlisting></para>
</sect2>
<sect2>
<title>Create device files that BASH needs</title>
<para><programlisting><prompt>bash#</prompt> mkdir /mnt/dev
<prompt>bash#</prompt> mknod /mnt/dev/console c 5 1</programlisting></para>
</sect2>
<sect2>
<title>Unmount the root disk</title>
<para><programlisting><prompt>bash#</prompt> cd /
<prompt>bash#</prompt> umount /mnt
</programlisting></para>
</sect2>
</sect1>
<sect1>
<title>Implementation</title>
<sect2>
<title>System startup</title>
<para>Follow these steps to boot the system:</para>
<itemizedlist>
<listitem>
<para>Restart the PC with the boot disk in the floppy drive.</para>
</listitem>
<listitem>
<para>When the <prompt>grub&gt;</prompt> prompt appears, 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>After the kernel loads, type <userinput>boot</userinput> and
press <keycap>Enter</keycap>.</para>
</listitem>
<listitem>
<para>Insert the root disk when prompted.</para>
</listitem>
</itemizedlist>
<para>If all goes well the screen should look something like the example
shown below.</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: ext2 filesystem found at block 0
RAMDISK: Loading 1440 blocks [1 disk] into ram disk... done.
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 178k freed
# _</screen></para>
</sect2>
<sect2>
<title>Testing what works</title>
<para>Try out a few of BASH's built-in commands to see if things are
working properly.</para>
<para><programlisting><prompt>bash#</prompt> echo "Hello World"
<prompt>bash#</prompt> cd /
<prompt>bash#</prompt> pwd
<prompt>bash#</prompt> echo *</programlisting></para>
</sect2>
<sect2>
<title>Noting what does not work</title>
<para>Try out a few other familiar commands.</para>
<para><programlisting><prompt>bash#</prompt> ls /var
<prompt>bash#</prompt> mkdir /var/tmp</programlisting></para>
<para>Notice that only commands internal to BASH actually work and that
external commands like <command>ls</command> and
<command>mkdir</command> do not work at all. This shortcoming is
something that can be addressed in a future phase of the project. For
now we should just enjoy the fact that our prototype boot / root diskset
works and that it was not all that hard to build.</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>