LDP/LDP/guide/docbook/Pocket-Linux-Guide/appendix-a.xml

613 lines
22 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<appendix id="a">
<title>Hosting Applications</title>
<sect1>
<title>Analysis</title>
<para>An operating system by itself is not much fun. What makes an OS
great is the applications that can be run on top of it. Unfortunately,
Pocket Linux currently does not have much room for anything other than
system programs. Still, it would be nice to expand the system just enough
to host some cool applications. Obviously a full-blown X-Windows GUI is
out of the question, but running a small console based program should be
within our reach.</para>
<para>Rather than doing a typical "hello world" program as an example,
application hosting will be demonstrated using a console based audio
player called mp3blaster. Building mp3blaster offers more technical
challenge than "hello world" and the finished product should be a lot more
fun. However, it should not be construed that a console-based jukebox is
the only application for Pocket Linux. On the contrary, after completing
this phase the reader should have the knowledge and tools to build almost
any console-based program he or she desires.</para>
<para>So what will it take to turn a pocket-sized GNU/Linux system into a
pocket-sized mp3 player? A few things are listed below.</para>
<itemizedlist>
<listitem>
<para>Add support for audio hardware.</para>
</listitem>
<listitem>
<para>Create space for the mp3blaster program.</para>
</listitem>
<listitem>
<para>Provide a convenient way to access audio files.</para>
</listitem>
</itemizedlist>
</sect1>
<sect1>
<title>Design</title>
<sect2>
<title>Support for audio hardware</title>
<para>There is a vast proliferation of audio hardware on the market and
each sound card has its own particular configuration. For details on how
to set up a particular sound card we can turn to the Sound-HOWTO
available from <ulink url="http://www.tldp.org">The Linux Documentation
Project</ulink>. In a broader sense, however, we can treat a sound card
like any other piece of new hardware. To add new hardware to a GNU/Linux
system we will need configure the kernel to recognize it and configure
<filename>/dev</filename> files on the root disk to access it.</para>
<sect3>
<title>Kernel support for audio</title>
<para>In order to support sound cards, a new kernel will have to be
built. It is very important that audio hardware support be configured
as built-in, because Pocket Linux is not set up to handle kernel
modules.</para>
</sect3>
<sect3>
<title>Root disk support for audio</title>
<para>Searching <filename>devices.txt</filename> for the keyword
"sound" will list quite a few possible audio devices, but usually only
<filename>/dev/dsp</filename> and <filename>/dev/mixer</filename> are
required to get sound from a PC. These two files control the digital
audio output and mixer controls, respectively.</para>
</sect3>
</sect2>
<sect2>
<title>Creating space for the program</title>
<para>Probably the easiest way to create more space for the mp3blaster
program is to mount an additional storage device. There are several
choices for mount points. So far <filename>/usr</filename>,
<filename>/home</filename> and <filename>/opt</filename> are all empty
directories and any one of them could be used to mount a floppy, CD-ROM
or additional compressed ramdisk image. The <filename>/usr</filename>
directory is a logical choice for a place to put an application, but
what about the choice of media? Mp3blaster and its required libraries
are too big to fit on a 1.44M floppy and burning a CD-ROM seems like a
lot of work for one little program. So given these constraints, the best
choice would be to put the program on a compressed floppy.</para>
<sect3>
<title>Mounting additional compressed floppies</title>
<para>Mounting CDs and uncompressed diskettes is easy, but what about
loading compressed images from floppy into ramdisk? It will have to be
done manually, because automatic mounting of compressed floppies only
works for the root diskette. And using <command>mount
/dev/fd0</command> will not work because there is no filesystem on the
diskette, there are only the contents of a gzip file. The actual
filesystem is contained inside the gzip file. So how can we mount the
filesystem buried beneath the gzip file? This puzzle can be solved by
examining at the steps used to create the familiar compressed root
disk floppy.</para>
<orderedlist>
<listitem>
<para>A ramdisk is created, mounted and filled with files.</para>
</listitem>
<listitem>
<para>The ramdisk device is unmounted.</para>
</listitem>
<listitem>
<para>The contents of the ramdisk are dumped to an image file
using <command>dd</command>.</para>
</listitem>
<listitem>
<para>The image file is compressed with
<command>gzip</command>.</para>
</listitem>
<listitem>
<para>The compressed image file is written to floppy with
<command>dd</command>.</para>
</listitem>
</orderedlist>
<para>If that is how the compressed image makes its way from ramdisk
to compressed floppy, then going from compressed floppy to ramdisk
should be as simple as running through the steps in reverse.</para>
<orderedlist>
<listitem>
<para>The compressed image file is read from floppy with
<command>dd</command>.</para>
</listitem>
<listitem>
<para>The image file is uncompressed with
<command>gunzip</command>.</para>
</listitem>
<listitem>
<para>The contents of the image file are dumped into ramdisk using
<command>dd</command>.</para>
</listitem>
<listitem>
<para>The ramdisk device is mounted.</para>
</listitem>
<listitem>
<para>The files are available.</para>
</listitem>
</orderedlist>
<para>We can cut out the intermediate image file by using a pipe to
combine <command>dd</command> and <command>gunzip</command> like this:
<command>dd if=/dev/fd0 | gunzip -cq &gt; /dev/ram1</command>. Now the
compressed floppy goes straight into ramdisk, decompressing on the
fly.</para>
</sect3>
<sect3>
<title>Root disk support for additional ramdisks</title>
<para>We already have kernel support for ramdisks, because we are
using a compressed root disk, but we will need to create more ramdisks
in <filename>/dev</filename>. Typically the kernel supports eight
ramdisks on <filename>/dev/ram0</filename> through
<filename>/dev/ram7</filename> with <filename>ram0</filename> being
used for the rootdisk. The <filename>devices.txt</filename> file
included in the Linux source code documentation will be helpful for
matching devices to their major and minor numbers.</para>
</sect3>
</sect2>
<sect2>
<title>Accessing audio files</title>
<para>The sample mp3 file that we will be using in our example is small
enough to fit on an uncompressed floppy disk so that there is no need to
burn a CD. However, serious music lovers may want to have the capability
to mount a custom CD-ROM full of tunes and that option will require
support for additional hardware.</para>
<sect3>
<title>CD-ROM hardware support</title>
<para>Most modern CD-ROM drives will use IDE devices like
<filename>/dev/hdc</filename> or <filename>/dev/hdd</filename>. To
support these CD-ROM drives we will have to configure IDE support in
the kernel and create the appropriate device files on the root
disk.</para>
</sect3>
<sect3>
<title>CD-ROM filesystem support</title>
<para>CD-ROMs have different filesystems than hard disks and floppies.
Most CD burning applications use a filesystem called ISO-9660 and have
the capability to support Joliet or Rockridge extensions. We will have
to include support for these filesystems in the kernel in order to
mount CD-ROMs.</para>
</sect3>
</sect2>
<sect2>
<title>Other required files</title>
<para>We will want to have all of mp3blaster's required libraries and
other supporting files available as part of the compressed
<filename>/usr</filename> image so that mp3blaster can run correctly.
The familiar <command>ldd</command> command can be used to determine
which libraries mp3blaster requires. Any additional libraries can be
placed in <filename>/usr/lib</filename>. Even though some of the
libraries may appear in <filename>/lib</filename> on the development
system, they can still go in <filename>/usr/lib</filename> on the Pocket
Linux system. The dynamic linker, <filename>ld-linux.so</filename>, is
smart enough to look in both places when loading libraries.</para>
<para>Because mp3blaster uses the curses (or ncurses) screen control
library there is one additional file we need. The curses library needs
to know the characteristics of the terminal it is controlling and it
gets that information from the terminfo database. The terminfo database
consists of all the files under the
<filename>/usr/share/terminfo</filename> directory and is very large
compared to our available disk space. But, since Pocket Linux only
supports the PC console, we only have one terminal type to worry about
and therefore need only one file. The piece of the terminfo database we
need is the file <filename>/usr/share/terminfo/l/linux</filename>,
because we are using a "Linux" terminal. For more information about the
subject of curses, see John Strang's book entitled "Programming with
Curses" available from <ulink url="http://www.oreilly.com">O'Reilly
publishing</ulink>.</para>
</sect2>
<sect2>
<title>Summary of tasks</title>
<para>Between sound cards, ramdisks, CD-ROMs and terminfo there is quite
a bit to keep track of. So let's take a moment to organize and summarize
the tasks necessary to make the pocket jukebox a reality.</para>
<itemizedlist>
<listitem>
<para>Create a new kernel disk that includes built-in support for
audio hardware, IDE devices and CD-ROM filesystems.</para>
</listitem>
<listitem>
<para>Create the appropriate <filename>/dev</filename> files on the
root disk to support audio hardware, additional ramdisks and IDE
CD-ROMs.</para>
</listitem>
<listitem>
<para>Install the <command>gunzip</command> utility to enable
decompression of the usr image.</para>
</listitem>
<listitem>
<para>Create a startup script to load a compressed image from floppy
into a ramdisk and mount the ramdisk on
<filename>/usr</filename>.</para>
</listitem>
<listitem>
<para>Create a compressed floppy that holds the mp3blaster program,
its required libraries and terminfo files.</para>
</listitem>
</itemizedlist>
</sect2>
</sect1>
<sect1>
<title>Construction</title>
<sect2>
<title>Create an enhanced boot disk</title>
<sect3>
<title>Build a new kernel</title>
<para><programlisting>bash# cd /usr/src/linux
bash# make menuconfig</programlisting></para>
<para>Be sure to configure support for the following:</para>
<itemizedlist>
<listitem>
<para>386 processor</para>
</listitem>
<listitem>
<para>Floppy disk</para>
</listitem>
<listitem>
<para>RAM disk</para>
</listitem>
<listitem>
<para>Second extended (ext2) filesystem</para>
</listitem>
<listitem>
<para>Virtual console</para>
</listitem>
<listitem>
<para>Audio hardware</para>
</listitem>
<listitem>
<para>CD-ROM hardware</para>
</listitem>
<listitem>
<para>ISO-9660 and Joliet filesystems</para>
</listitem>
</itemizedlist>
<para><programlisting>bash# make dep
bash# make clean
bash# make bzImage</programlisting></para>
</sect3>
<sect3>
<title>Copy the kernel to diskette</title>
<para>Place the boot disk in drive fd0</para>
<para><programlisting>bash# mount /dev/fd0 /mnt
bash# cp /usr/src/linux/arch/i386/boot/bzImage /mnt/boot/vmlinuz</programlisting></para>
</sect3>
<sect3>
<title>Unmount the boot disk</title>
<para><programlisting>bash# cd /
bash# umount /mnt</programlisting></para>
</sect3>
</sect2>
<sect2>
<title>Create an enhanced root disk</title>
<sect3>
<title>Create additional device files</title>
<sect4>
<title>IDE CD-ROM</title>
<para><programlisting>bash# mknod -m640 ~/staging/dev/hdc b 22 0
bash# mknod -m640 ~/staging/dev/hdd b 22 64</programlisting></para>
<para>Optionally create additional IDE devices.</para>
</sect4>
<sect4>
<title>Ramdisk</title>
<para><programlisting>bash# mknod -m 640 ~/staging/dev/ram1 b 1 1
bash# mknod -m 640 ~/staging/dev/ram2 b 1 2
bash# mknod -m 640 ~/staging/dev/ram3 b 1 3
bash# mknod -m 640 ~/staging/dev/ram4 b 1 4
bash# mknod -m 640 ~/staging/dev/ram5 b 1 5
bash# mknod -m 640 ~/staging/dev/ram6 b 1 6
bash# mknod -m 640 ~/staging/dev/ram7 b 1 7</programlisting></para>
</sect4>
<sect4>
<title>Audio</title>
<para><programlisting>bash# mknod -m664 ~/staging/dev/dsp c 14 3
bash# mknod -m664 ~/staging/dev/mixer c 14 0</programlisting></para>
</sect4>
</sect3>
<sect3>
<title>Install the gunzip binary</title>
<para><programlisting>bash# cd /usr/src/gzip-1.2.4a
bash# export CC="gcc -mcpu=i386"
bash# ./configure --host=i386-pc-linux-gnu
bash# make
bash# strip gzip
bash# cp gzip ~/staging/bin
bash# ln -s gzip ~/staging/bin/gunzip</programlisting></para>
<para>Don't forget to verify library requirements, check the ownership
and check permissions on the gzip binary.</para>
</sect3>
<sect3>
<title>Write a startup script to mount a compressed floppy</title>
<para>Use a text editor to create the following script and save it as
<filename>~/staging/etc/init.d/usr_image</filename></para>
<para><programlisting>#!/bin/sh
#
# usr_image - load compressed images from floppy into ramdisk and
# mount on /usr.
#
echo -n "Is there a compressed diskette to load for /usr [y/N]? "
read REPLY
if [ "$REPLY" = "y" ] || [ "$REPLY" = "Y" ]; then
echo -n "Please insert the /usr floppy into fd0 and press &lt;ENTER&gt;."
read REPLY
echo "Clearing /dev/ram1."
dd if=/dev/zero of=/dev/ram1 bs=1k count=4096
echo "Loading compressed image from /dev/fd0 into /dev/ram1..."
(dd if=/dev/fd0 bs=1k | gunzip -cq) &gt;/dev/ram1 2&gt;/dev/null
fsck -fp /dev/ram1
if [ $? -gt 1 ]; then
echo "Filesystem errors on /dev/ram1! Manual intervention required."
else
echo "Mounting /usr."
mount /dev/ram1 /usr
fi
fi
#
# end of usr_image</programlisting></para>
<para>Configure the script to run right after root is mounted.</para>
<para><programlisting>bash# ln -s ../init.d/usr_image ~/staging/etc/rcS.d/S21usr_image</programlisting></para>
</sect3>
<sect3>
<title>Create a compressed root disk</title>
<para><programlisting>bash# cd /
bash# dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
bash# mke2fs -m0 /dev/ram7
bash# mount /dev/ram7 /mnt
bash# cp -dpR ~/staging/* /mnt
bash# umount /dev/ram7
bash# dd if=/dev/ram7 of=~/phase8-image bs=1k
bash# gzip -9 ~/phase8-image</programlisting></para>
<para>Insert the diskette labeled "root disk" into drive fd0.</para>
<para><programlisting>bash# dd if=~/phase8-image.gz of=/dev/fd0 bs=1k</programlisting></para>
</sect3>
</sect2>
<sect2>
<title>Create a compressed /usr disk for mp3blaster</title>
<para>The compressed /usr diskette will be created in using the same
process that is used to create the compressed root disk. We will copy
files to a staging area, copy the staging area to ramdisk, compress the
ramdisk and write it to diskette.</para>
<sect3>
<title>Create a staging area</title>
<para><programlisting>bash# mkdir ~/usr-staging
bash# cd ~/usr-staging
bash# mkdir bin lib
bash# mkdir -p share/terminfo/l</programlisting></para>
</sect3>
<sect3>
<title>Install the mp3blaster program</title>
<para>Download the latest version of mp3blaster source code from its
home at <ulink
url="http://www.stack.nl/~brama/mp3blaster/">http://www.stack.nl/~brama/mp3blaster/</ulink>.</para>
<para><programlisting>bash# cd ~/usr/src/mp3blaster-3.2.0
bash# ./configure
bash# make
bash# cp src/mp3blaster ~/usr-staging/bin</programlisting></para>
</sect3>
<sect3>
<title>Copy additional libraries and terminfo</title>
<para>Use <command>ldd</command> to find out which libraries are
needed for mp3blaster.</para>
<note>
<para>The following is an example from the author's development
system. It is possible that different systems may yield slightly
different results in terms of library requirements.</para>
</note>
<para><programlisting>bash# cd ~/usr-staging/lib
bash# ldd ~/usr-staging/bin/mp3blaster
bash# cp /usr/lib/ncurses.so.5.0 .
bash# cp /usr/lib/stdc++.so.3 .
bash# cp /lib/libm.so.6 .
bash# cp /usr/lib/libgcc_s.so.1 .
bash# cd ~/usr-staging/share/terminfo/l
bash# cp /usr/share/terminfo/l/linux .</programlisting></para>
</sect3>
<sect3>
<title>Make a compressed image and copy it to diskette</title>
<para><programlisting>bash# cd /
bash# dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
bash# mke2fs -m0 /dev/ram7
bash# mount /dev/ram7 /mnt
bash# cp -dpR ~/usr-staging/* /mnt
bash# umount /dev/ram7
bash# dd if=/dev/ram7 of=~/mp3blaster-image bs=1k
bash# gzip -9 ~/mp3blaster-image</programlisting></para>
<para>Insert the diskette labeled "mp3blaster" into drive fd0.</para>
<para><programlisting>bash# dd if=~/mp3blaster-image.gz of=/dev/fd0 bs=1k</programlisting></para>
</sect3>
</sect2>
<sect2>
<title>Create a data diskette for testing</title>
<para>Go to the Internet site <ulink
url="http://www.paul.sladen.org">http://www.paul.sladen.org</ulink> and
download the mp3 file of Linus Torvalds pronouncing "Linux." The direct
link is: <ulink
url="http://www.paul.sladen.org/pronunciation/torvalds-says-linux.mp3">http://www.paul.sladen.org/pronunciation/torvalds-says-linux.mp3</ulink>.
Create a Second Extended (ext2) filesystem on a floppy and copy the mp3
file onto the diskette.</para>
</sect2>
</sect1>
<sect1>
<title>Implementation</title>
<sect2>
<title>System Startup</title>
<orderedlist>
<listitem>
<para>Boot from the kernel diskette.</para>
</listitem>
<listitem>
<para>Insert the root floppy when prompted.</para>
</listitem>
<listitem>
<para>When prompted for a /usr diskette, say 'Y'.</para>
</listitem>
<listitem>
<para>Insert the mp3blaster diskette and press
<keycap>Enter</keycap>.</para>
</listitem>
</orderedlist>
</sect2>
<sect2>
<title>Verify that the /usr diskette loaded properly</title>
<para><programlisting>bash# mount
bash# ls -lR /usr</programlisting></para>
</sect2>
<sect2>
<title>Check the audio device initialization</title>
<para><programlisting>bash# dmesg | more</programlisting></para>
<para>If everything worked there should be a line or two indicating that
the kernel found the audio hardware. The example below shows how the
kernel might report a Yamaha integrated sound system.</para>
<para><screen>ymfpci: YMF740C at 0xf4000000 IRQ 10
ac97_codec: AC97 Audio codec, id: 0x4144:0x5303 (Analog Devices AD1819)
</screen></para>
</sect2>
<sect2>
<title>Test audio output</title>
<para><programlisting>bash# echo "Garbage" &gt; /dev/dsp</programlisting></para>
<para>A short burst of static coming from the PC speakers indicates that
sound is working.</para>
</sect2>
<sect2>
<title>Play a sample file</title>
<para>Insert the diskette containing the sample audio file.</para>
<para><programlisting>mount /dev/fd0 /home
bash# /usr/bin/mp3blaster</programlisting></para>
<para>Use mp3blaster to select and play the file
<filename>/home/torvalds-says-linux.mp3</filename>. Use mp3blaster's
mixer controls to adjust the volume as needed.</para>
</sect2>
<sect2>
<title>System shutdown</title>
<para>Bring the system down gracefully with the
<command>shutdown</command> command.</para>
</sect2>
</sect1>
</appendix>