From: eonu24@castle.ed.ac.uk (I Reid)
Subject: Custom setups: RFD
Date: 11 Apr 92 00:56:07 GMT

This article is posted as a "Request for Discussion" (RFD) although I
realise at the outset that I may be alone in my viewpoint :-(. If I am
then please feel free to send me a nice mailer telling me to shut up and
stop wasting bandwidth. 

The main bit
============

Some facts:

1. Linux is getting very popular and is being run on a great variety
   of i386 and above based machines without significant problems.

2. One of the things people like best about linux (apart from it being
   free) is that full source to the kernel is available at all the
   archive sites and rebuilding the kernel is a relatively easy thing
   to do.

3. Different people want greatly differing things from Linux but above
   all the consensus is that the kernel should be small and fast.


So, putting these things together we come up against a problem....
what should be "standard" in the Linux kernel and what should be
optional. Take, for example, two different setups run on two different
machines by two different people.

Machine 1
=========

i386 based machine with a single IDE drive, a 2400 baud dialup
connection to another unix box for mail/usenet etc and a null modem
connection to a nearby dos based pc (with a printer attached to it).
Runs almost excvlusively in single user mode.    

Machine 2
=========

i386 based machine with a single SCSI drive, fast modem connection to
a terminal concentrator capable of compressed slip, printer attached
directly to machine. Runs in multi-user mode for much of the time.

Some things spring immediately to mind (with respect to what should be
"standard" in the kernel):

1. Both users will probably want things like support for ps in the kernel.

2. User 1 (Machine 1) has no need at the moment for SCSI support
   compiled into his kernel although he may want it later so would
   like the option. User 2 on the other hand can't use his SCSI drive
   without this support but has no need for non SCSI hard drive
   stuff in his kernel.

3. User 1 is not directly connected to the Internet and so doesn't
   need intermachine interprocess communication in the kernel (i.e.
   Unix domain only in socket speak). User 2 on the other hand has a
   real world connection that is fast enough to support intermachine
   interprocess communication and probably wants it in his kernel.

4. User 2 wants support for parallel devices such as the printer port
   whereas user 1 doesn't.

5. User 2 probably wants X windows with support for viewing
   applications run on remote machines, user 1 can't realistically do
   this (however appealing it might be!) so doesn't want the kernel
   overhead of supporting something he can't use.

As you can see, for each person to have the smallest, fastest kernel
that is well matched to their needs/facilities a number of decisions
have to be made. So, what do I propose....


1. A standard release of the full kernel source with ALL available
   options available in the source code.

2. A well documented configuration file to allow EASY changing of
   setups and trouble free building of custom kernels. This should be
   very wide ranging and should cover all possibilities.

3. A bare minimum of "must be in there" things in the smallest possible
   kernel.

4. Good, clear notes on configuration and rebuilding the kernel (I've
   included the ones I posted (which are neither very good or clear
   but they seemed to help people) at the end of this article)

5. Intelligent conditional compilation e.g. warns you if you have
   absolutely no hard drive support in your selected configuration.

Some of this may be in 0.95c (haven't had a chance to look yet... I
know the national keyboard selection is now done more sensibly) but I
think anyone writing kernel level code should be aware that however
wonderfull their code, there are those who need it and those who
don't. Should needs change it should be easy to adjust things (by easy I
mean a 1 (or so) line change in a master config file).

Iain

p.s. here are those notes on kernel recompilation. They were written
for 0.95a and were originally posted with notes on applying the
patches for and installing ps. This was written for 0.95a not 0.95c
                                                        ^         ^
                                                        |         |
                                     Please note________|_________|

(which I haven't had a chance to look at yet) so buyer beware.


===========cut=here=================================================
Over the past few days I have been trying to answer a number of
questions about building ps0.95 so I decided to write what I hope will
be the definitive answer to 2 questions:

1. How do I rebuild the linux 0.95a kernel
2. How do I compile and install ps (095 version)

As usual, I welcome all and any comments to Iain_Reid@ed.ac.uk and I
will try to reply to them if the message warrants it.

============================================================================
1. Rebuilding the 0.95a kernel
==============================

Full source code for the linux kernel is available at the archive sites
and it is useful to know how to rebuild the kernel from this code. This
is very easy to do.

You will need - the kernel source for the latest version (0.95a)
              - a C compiler (Gcc 1.40 (newgcc in the archives) or gcc 2.0)
              - 1.5 - 2 Mb of free disk space


The standard place for the linux source tree is in /usr/src/linux so
if you don't have a /usr/src directory you will need to create one
with mkdir. Once you have done this move the tar file of the kernel
source (probably called linux-0.95a.tar) to /usr/src and type

tar -xvf linux-0.95a.tar

You should see a whole load of file names flashing by on the screen.
This is good. When tar finishes you should have a directory called
/usr/src/linux and this will have a number of subdirectories. You will
probably want to hang on to the original tar in case you want an
original source tree but you can compress it up if you like.... i.e.
you don't need it again for this.

If you are using gcc 1.40 you will have to make two two byte changes
to get the source to compile properly. In the files linux/kernel/Makefile
and linux/kernel/chr_drv/Makefile you will find a bit that looks like this
quite near the top

# gcc2 doesn't have these:
# GCC_OPT = -fcombine-regs

Gcc2 may not have these but gcc 1.40 does and it will die saying
something like this

gcc -Wall -O -fstrength-reduce -fomit-frame-pointer   -finline-functions -nostdi
nc -I../include  -c -o fork.o fork.c
Program  got fatal signal 143.
*** Error code 1
 
Stop.
*** Error code 1
 
Stop.
 
if you try to compile it. The way to fix this is to uncomment a line i.e.

# GCC_OPT = -fcombine-regs 

becomes

GCC_OPT = -fcombine-regs

The other changes you might want to make are in 

============================================================================
1. linux/kernel/blk_drv/hd.c where there is the line

static int reset = 1;

If you have a lot of problems with the HD timeout message then change
this to read

static int reset = 0;

This is a TEMPORARY hack so don't forget about it! Do NOT do this
before mkfs'ing your filesystem 'cos errors won't be handled properly
with this change (I'm told).
============================================================================

============================================================================
2. linux/kernel/chr_drv/keyboard.S where there is a bit that says


/* KBD_FINNISH for Finnish keyboards
 * KBD_US for US-type
 * KBD_GR for German keyboards
 * KBD_FR for Frech keyboard
 * KBD_UK for British extended keyboard
 * KBD_DK for Danish keyboard
 */
#define KBD_FINNISH

you should change this to whatever is appropriate for you e.g.

#define KBD_UK for me
============================================================================

============================================================================
3. linux/Makefile where there is a bit that says

# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
# default of FLOPPY is used by 'build'.
#
ROOT_DEV=/dev/hdb1

Change this to be whatever your root device is (the device you did
mkfs -c for). For me this would be /dev/hda2 'cos I have a dos
partition on /dev/hda1
============================================================================

Ok, now cd to /usr/src/linux and type

make all

If your compiler is set up properly you should see many lines like

gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions
 -nostdinc -I../include  -c -o fork.o fork.c

(with different source file names obviously). This should continue for
quite a while (7-8 minutes on my heavily cached 386-33) so time for a
quick cup of tea and a chat with your flatmates.

N.b. don't worry if it seems to hang while compiling floppy.c.... give
it a few seconds and it should burst back into life.... it's thinking :-)

If it gets all the way through there will be a file called Image
created in /usr/src/linux. This is the new bootimage and you can put
it onto a floppy in /dev/PS0 (a 3.5" 1.44Mb floppy on my machine) by
typing

dd bs=8192 if=Image of=/dev/PS0

You can do this automatically by typing make disk instead of make all
(above) if you wish.

Congratulations! You have just rebuilt the linux kernel and created a
new boot floppy. Time to sync, reboot your machine and test it. I
hope you didn't overwrite your original bootimage; 'cos if you did then
what are going to use to boot up if the new bootimage is faulty?? Ah,
the value of forward planning :-)

/***********************************************************/

2. How to compile and install the ps and free commands in Linux v0.95a
===================================================================

You will need: - source for the 0.95a kernel
               - source for ps
               - patch
               
I'm assuming that you are happy rebuilding the kernel (as above) 'cos
you need to be able to do this to install ps.

Take the tar file containg the ps source (say ps.tar) and place it in
/usr/src/linux (or wherever you keep your kernel source. Type tar xvf
ps.tar (or whatever) to create a directory ps (within /usr/src/linux)
to contain the ps source and kernel patches.

Read the file /usr/src/linux/ps/README (especially the bit marked
installation). Cd to /usr/src/linux and type the following

patch -p0 < ps/patches >patch.result 2>&1

Now have a look at the file patch.result in the current directory.
Most of it should indicate success, but at the end is a bit that reads

Hmm...  The next patch looks like a new-style context diff to me...
The text leading up to this was:
==========================
|*** mm/swap.c.Org      Fri Mar  6 16:43:18 1992
|--- mm/swap.c  Tue Mar 10 19:03:19 1992
==========================
Patching file mm/swap.c using Plan A...
Hunk #1 failed at 156.
Hunk #2 succeeded at 173 with fuzz 1 (offset -3 lines).
Hunk #3 failed at 182.
2 out of 3 hunks failed--saving rejects to mm/swap.c#

Make a note of these details and cd to /usr/src/linux/mm. There you
will find a file called swap.c# where the rejects have been saved. It
looks like this

===================================================================
***************
*** 156,160 ****
        static int page_entry = -1;
        int counter = VM_PAGES;
!       int pg_table = 0;
  
  repeat:
--- 156,160 ----
        static int page_entry = -1;
        int counter = VM_PAGES;
!       int pg_table = 0, d_entry;
  
  repeat:
***************
*** 181,186 ****
                        goto repeat;
                }
!               if (try_to_swap_out(page_entry + (unsigned long *) pg_table))
                        return 1;
        }
        printk("Out of swap-memory\n\r");
--- 182,189 ----
                        goto repeat;
                }
!               if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
!                       --task[d_entry >> 4]->rss;
                        return 1;
+               }
        }
        printk("Out of swap-memory\n\r");
===================================================================

Taking the first patch first. This means that patch tried to
find lines 156-160 in swap.c (which it thinks look like this)

        static int page_entry = -1;
        int counter = VM_PAGES;
!       int pg_table = 0;
  
  repeat:

and replace them with

        static int page_entry = -1;
        int counter = VM_PAGES;
!       int pg_table = 0, d_entry;
  
  repeat:

Notice the exclamation mark indicating the changed line. What you
need to is open swap.c with an editor, find the line with int pg_table
= 0; (line 158 in my unaltered copy) and add the d_entry bit.


The second one is more slightly more tricky. Patch thinks lines
181-186 look like this

                        goto repeat;
                }
!               if (try_to_swap_out(page_entry + (unsigned long *) pg_table))
                        return 1;
        }
        printk("Out of swap-memory\n\r");

Unfortunately they don't so you need to find this bit yourself (look
at line 187 for a match for the exclamation marked line above) and
then edit it to incorporate the patch (below)

                        goto repeat;
                }
!               if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
!                       --task[d_entry >> 4]->rss;
                        return 1;
+               }
        }
        printk("Out of swap-memory\n\r");

In this case you need to alter lines 187-189 to read

        if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
                --task[d_entry >> 4]->rss;
                return 1;
        }

instead of 

        if (try_to_swap_out(page_entry + (unsigned long *) pg_table))
                return 1;

and ignore the goto repeat; line 'cos it's not in the original.

Can you see the sense in this? It's really pretty easy once you get
the hang of it.

Ok, you've patched in all the patches (some automatically and some by
hand. Now cd /usr/src/linux and type

make clean
make all

This should remove any out of date files and build a new bootimage.

You should sync and reboot with the new bootimage to make sure that
everything is ok. This is exactly the same as above.

NB: You must reboot and be running the new kernel for the rest of this
to work properly.

Next, having rebooted and satisfied yourself that everything is
alright you type cd /usr/src/linux/ps and type

make ps

If it complains about not finding cc then add a line saying CC = gcc to
the start of the makefile or create a link to gcc and call it cc i.e.

ln -s /usr/bin/gcc /usr/bin/cc

You will need to edit the makefile if your linux source is not
in/usr/src/linux- see ps/README for details.

Last, but not least.... type

ps U /usr/src/linux/tools/system

to build the ps-database.

"Every time you boot a new kernel you have to do a 'ps U' to update
the psdatabase, after doing this you can remove the system file or
do a make clean.

The pathname to the system binary is stored in the psdatabase, so
you only have to specify it if you have moved your source tree or
if you are creating the psdatabase for the first time. The psdatabase
is always '/etc/psdatabase'.

You can install ps suid root or sgid kmem, read access to /dev/kmem
and /dev/mem is needed." - quoted from ps/README


Where you install is up to you.... I run single user so I can do what
I like but I think the recommended place is /usr/bin.

Hope this clears everything up.

Iain
============================================================

From: tytso@ATHENA.MIT.EDU (Theodore Ts'o)
Subject: Re: Custom setups: RFD
Reply-To: tytso@athena.mit.edu
Date: Sat, 11 Apr 1992 03:00:25 GMT

May I suggest that instead of describing in long and careful detail how
to fix the failed patch hunks in swap.c, you simply provide a new patch
file which doesn't fail?  I suspect it would take up less room than your
description, and would be simpler for most people to do.

As to your point about a configuration process, I agree with you.  Linux
is rapidly approaching the point where it could really use a
/usr/etc/config program ala BSD to build its Makefile.  Although I
haven't had the time in a while to do any kernel hacking in a while
(unfortunately, sigh....) I will note that the config program is freely
available in /packages/bsd-sources/usr.sbin/config on ftp.uu.net.
Perhaps someone would be willing to take a whack at adapting it for
Linux?  If not, when I manage to find some time I'll look into it.

                                                        - Ted