So far I have focussed on what the packages do. Here I will offer what clues I can about making a minimal Linux system from source.
There is more than one way to go about building a system. But the way I did it seems to have worked out ok, so this account may be helpful to you.
I used a dedicated machine - an old Wang 386sx of almost zero dollar value. I did a minimal install of Red Hat 6.0 to be the ``source'' system, and allocated a ``target'' partition where I built the system. In the old Wang, I have a 3G hard disk partitioned as follows:
hda1 480M where I built the system (``target'') hda2 20M boot partition for the Red Hat system hda3 50M swap hda4 2500M extended partition containing hda5 hda5 2500M Red Hat 6.0 root file system (``source'')
There is no real point in having the logical partition hda5 inside an extended partition, hda4. That's just what Red Hat's Disk Druid did when I installed. You only need the base Red Hat system, plus development tools and libraries. It used about 250M of disk space. You could do this exercise with a 1G disk, or a pair of 500M disks.
Older PC hardware, mostly 486's and earlier, have an annoying limitation in their bios. They can not read from a hard disk past the first 512M. This is not too much of a problem for Linux, because once it is up, it does its own disk io. But for Linux to get loaded by these old machines, it has be reside somewhere below 512M. This is why I have both the whole target partition, and the small boot partition for the source system below the 512M mark.
You may wish to actually use the target system, rather than simply build it for
a learning exercise. In this case, you would need to go a bit beyond what is
described in this document. You would need to install gcc
and other
development tools so that the system could build itself. Once this was done,
you could wipe the ``source'' system and use its space on the target. Perhaps
you could move the /usr
directory to it.
The Wang only has 8M of RAM in it. I think this is
the main reason that the compile of glibc
took 90 hours (and spanned
millenia). It ``only'' took 6 hours on my 486 with 32M. My guess is that if
I had 16M in the Wang, it would have taken 24 to 48 hours. Kernel compiles
take about 8 hours.
I made an ext2 file system on the target partition using mke2fs
, and
created directories by hand using mkdir
. I didn't have it at the time,
but the
Filesystem Heirarchy Standard would have been a
good thing to follow.
In the fstab
of the source system, I set up the target partition to
be mounted at /mnt/target
. Most of the packages have a configuration
option for where they are to be installed. By default, the ``base'' directory
for a package installation is /
, ie you want to install it on the
system where it is being built. I used these options to set the base install
directory to /mnt/target
. For example, to install a GNU package to
/mnt/target
, you configure as follows
./configure --prefix=/mnt/target
There is a problem with this approach if some of the packages of the target
system are more recent than their equivalents on the source system. For
example, I installed ncurses 5 on the target system, but the source had 4.
When compiling, by default the headers and libraries of the source system
are used. To fix this you need to set variables or configuration parameters
to tell it where the headers and libraries that you want it to use are.
Sometimes all you can do is hack the Makefile
. If you look at the
output that is produced while a program is being compiled, the -I
flags tell it where to look for headers, and the -L
flags tell it
where to look for libraries. Look for a variable called LDFLAGS
.
This is probably where you can slip a couple extra of these flags in, and
make it look where you want. For example in the Makefile
for the
procps
package, I got it to use the right libraries by adding
-L /mnt/target/lib
LILO is installed in the master boot record by Red Hat. I installed LILO for
the target system in the boot sector of the target partition. I then added
the following to /etc/lilo.conf
in the source system
other=/dev/hda1 label=target
and reran lilo
. This has the effect that when you first boot,
one of the options LILO gives you is ``target''. If you choose this, you
get a second instance of LILO which boots the target system. This might
seem crazy, but it allows the separation of the system you are building
from the system you are using to build it with.
If you have a command called thingy
on a Linux system with RPM, and
want a clue about where to get the source from, you can use the command:
rpm -qif `which thingy`
And if you have a Red Hat source CD, you can install the source code using
rpm -i /mnt/cdrom/SRPMS/what.it.just.said-1.2.srpm
Once you have a bash prompt, the next stage is to get your system able to self replicate. I have not done this yet, but the following are some of the things you will need to install to do this.