Installing Olde Fashioned Gentoo
You will need access to binary package tarballs, so you need an existing Gentoo install to cherry pick.
This install method is not for Gentoo beginners.
Still reading ... don't say you were never warned. The usual caveat applies, if it breaks, you can keep the pieces.
As this document is aimed at users with at least one Gentoo install to their credit, it is not a keystroke by
keystroke guide, unlike the Handbook. The handbook steps are not repeated here, there is just some general
references to it from time to time.
The steps are:-
- partition the target drive following the handbook
- quickpkg the packages needed to form a stage1 (see below)
- use tar to unpack enough so that a chroot is vialble
- set up package.mask to keep out unwanted junk
- emerge a few key things to satisfy virtuals
- use emerge @system to install the system set
- follow the handbook to install cron, a logger and a bootloader of your choice
- Install a kernel
- configure grub
- review and edit configurooin settis
- reboot to test
This document describes how to install Gentoo with a static /dev using the packages from an existing install as a seed.
What You Get
A modern gentoo base system but without all the bells and whistles added in recent years. Olde Fashioned Gentoo is more about what you don't get.
You dont get
- udev - you get a static dev
- systemd - why would you want it anyway
- pulseaudio - I've not known this to actually add anything
- hotplug support
- auto mounting of any sort - use mount by label
- auto module loading
- device detection in Xorg
Access to the Gentoo Handbook is required as this guide makes frequent references to it,
there is no point in repeating the handbook here.
Partitioning and Making Filesystems
How To Get Started
The current stage 3 already has many of the things we want to avoid, so its not a good starting point, so we won't start there.
Instead we will fetch some binaries, or you can quickpkg your own, then untar them to a new filesystem tree.
After the required binaries are unpacked, there is a polluted stage1 environment to work in.
Making Your Filesystem Tree
Follow the Gentoo Handbook up to and including making your filesystems and mounting all the bits at /mnt/gentoo.
Do not fetch or install a stage3 tarball.
I will be using Logical Volumes on top of raid5 because its easier to recyle the volumes than it is with real partitions and if the logical volumes
are the wrong size, they can be resized. I happen to have lvm on raid5 space free. This means that I will also describe the initramfs to
get the raid assembled and Logical Volumes active. Users installing to real partitions should not need the initramfs.
Preparing the Chroot
Copying Needed Files
Make sure your current install is up to date, you will be sharing its portage tree, distfiles, and a few binary packages with Olde Fashioned Gentoo
Code Listing 3.1: Copying Key /etc files
mkdir -p /mnt/gentoo/etc/portage
cp -a /etc/portage /mnt/gentoo/etc
cp /etc/group /mnt/gentoo/etc/group
cp /etc/passwd /mnt/gentoo/passwd
cp /etc/shadow /mnt/gentoo/shadow
cp /etc/profile /mnt/gentoo/etc/profile
cp /etc/fstab /mnt/gentoo/etc/fstab
cp /etc/resolv.conf /mnt/gentoo/etc/resolv.conf
cp /etc/locale.gen /mnt/gentoo/etc/locale.gen
cp /etc/localtime /mnt/gentoo/etc
cp -a /etc/portage /mnt/gentoo/etc/
Edit /mnt/gentoo/etc/locale.gen to include only the locales you need. The default is to build all locales.
Instructions are in the comments in the file
Code Listing 3.2: Edit /mnt/gentoo/etc/locale.gen
nano -w /mnt/gentoo/etc/locale.gen
Make mountpoints for special filesystems and other directories that would have been provided by the stage 3.
Code Listing 3.3: Making mount points for special filesystems
Change the permissions on /mnt/gentoo/tmp to 1777
Setting the chroot /var
Portage needs some workspace in the chroot with a special mode set.
Code Listing 3.4: Making Portage Workspace
mkdir -p /mnt/gentoo/var/tmp
chmod 1777 /mnt/gentoo/var/tmp
mount -t tmpfs tmpfs /mnt/gentoo/var/tmp
If your make.conf does not contain FEATURES=buildpkg to save binary packages of everything you build, you will need to use
quickpkg --include-config=y <package>
to produce the required binary packages from your install
This is a good time for a break if you need to do the install in two goes. To contine, Mount the filesystems and do the normal chroot steps.
Borrowing From your Main Install
Its quite safe to bind mount /usr/portage and /usr/portage/distfiles inside the chroo, but not
/usr/portage/packages as different USE flags will apply to packages built inside and outside the chroot.
Looking forward, lets cheat a little - unpack suffcient to chroot and use emerge -k but no more. Thats almost like stage1 install but there are some important differences.
emerge cannot be used until we are in the chroot and the chroot does not exist until we unpack some things there. Its a little chicken and egg. However,
the binary packages are tarballs with extra data appended. They can be unpacked with tar, provided we ignore the warning about extra garbage at end ignored.
Making the chroot
Code Listing 4.1: Setting make.profile
ln -s ../usr/portage/profiles/default/linux/amd64/13.0/desktop make.profile
Having made the packages we need, making the chroot is only a question of untaring them there. We will need
glibc (everything uses that) bash, portage and python at the very least.
Make friends with tab completion before you attempt the following. Type a few letters of a path name and press tab.
If the fragment is ambiguious, the alternatives will be shown. Type a few more letters and press tab again.
Important: Version numbers will vary with time and your own preferences they are not a cause for concern - choose the most recent version
Code Listing 4.2: Unpacking some key tarballs
tar xpf app-shells/bash-<ver>.tbz2 -C /mnt/gentoo
tar xpf dev-lang/python-<ver>.tbz2 -C /mnt/gentoo
tar xpf dev-lang/python-<ver>
tar xpf sys-libs/glibc-<ver>.tbz2 -C /mnt/gentoo
tar xpf sys-libs/ncurses-<ver> -C /mnt/gentoo
tar xpf sys-libs/zlib-<ver>.tbz2 -C /mnt/gentoo
tar xpf app-arch/bzip2-<ver>.tbz2 -C /mnt/gentoo
tar xpf app-arch/tar-<ver> -C /mnt/gentoo
tar xpf sys-apps/portage-<ver>.tbz2 -C /mnt/gentoo
tar xpf sys-apps/coreutils-<ver>tbz2 -C /mnt/gentoo
tar xpf sys-apps/findutils -C /mnt/gentoo
tar xpf sys-apps/acl-<ver>.tbz2 -C /mnt/gentoo
tar xpf sys-apps/sed-<ver>.tbz2 -C /mnt/gentoo
tar xpf sys-apps/attr-<ver>.tbz2 -C /mnt/gentoo
tar xpf app-admin/eselect-python -C /mnt/gentoo
tar xpf app-admin/eselect-<ver> -C /mnt/gentoo
tar xpf app sys-devel/gcc-config-<ver> -C /mnt/gentoo
tar xpf sys-devel/gcc-<ver> -C /mnt/gentoo
tar xpf sys-apps/sandbox-<ver> -C /mnt/gentoo
ln -s /usr/x86_64-pc-linux-gnu/binutils-bin/2.23.1/nm nm
ln -s /usr/bin/gawk /bin/awk
/bin/sh -> bash
/usr/bin/as -> x86_64-pc-linux-gnu-as
Mount /proc and but not /dev inside the chroot. We will be using a static /dev, so we have to emerge dev-static
With /dev bind mounted in the normal way, our static dev would go into the parents devtmpfs which is in RAM.
Purists should use mknod to make /dev/null and /dev/console in the chroot but cp -a works too.
Code Listing 4.3: Mounting Special Filesystems
mount -t proc proc /mnt/gentoo/proc
Entering the chroot
Code Listing 4.4: Entering the chroot
chroot /mnt/gentoo /bin/bash
Python is not set up in the chroot yet. Almost everything we want uses it, so fix that right now
Code Listing 4.5: Selecting Python
eselect python set 2
eselect python list
Verify that python 3.x is selected - the active python has the blue * after its name. Python is needed to set the chroot environment
Set the profile from inside the chroot
Code Listing 4.6: Setting the chroot environment
export PS1="(chroot) $PS1"
Things to fix or document more thorougly
/usr/lib should by a symlink to /usr/lib64 move stuff around if not
emerge sys-fs/static-dev ... see Bug 469620
Setting up package.mask
This is important. Enter the package atoms that you do now want to see installed ever.
Code Listing 4.7: Content of package.mask
# go back to a static /dev
Add in anything else you can think of they you really don't want.
Always use -av with emerge and add more things as they come to mind. mdev might need to be there too.
Setting up package.use
This section is only required if you use raid, lvm or have a separate /usr. You will need some packages built with the static USE flag.
Code Listing 4.8: Content of package.use
# static bits and pieces for an initrd
# to keep perl users happy
Setting USE= in make.conf
Setting Up Your Own Static Overlay
A number of packages that are required for a modern Gentoo system require udev. In some the dependency can be avoided by careful use of USE flags.
Others like lvm2 and Xorg have udev included IUSE. Make a local overlay called static_dev, copy these ebuilds there and remove all references to udev.
Warning: This may break these packages in ways I'm totally unaware of
There is a bug in the static-dev ebuild (Bug 469620) that prevents it installing if /proc/mounts reports that a dynamic /dev manager is in use.
Either patch static-dev in the overlay or unmount /proc from /mnt/gentoo/proc while
Code Listing 4.9: Emerging static-dev
Adding to /dev
static-dev is a good start but its not moved on in a very long time. Add some of the newer entries required.
- mknod all of the /dev/sd* entries you need
- mknod any /dev/md* kernel multipe device entries required
- mknod any /dev/dm-X device mapper entries required
Don't forget nodes for removable storage devices.
lvm2 insists on udev lsusb builds but gives unable to initialize libusb: -99
Sorting Out the Minimal Chroot
A lot of system set packages are missing, not everything will build cleanly to start with and things that do build will report collisions.
The collisiosn can be safely ignored. They are expected as the files that are in the chroot have been installed without registering them
Code Listing 4.10: Emerging the System Set
emerge @system --keep-going --with-bdeps=y
Add --nodeps to the above emerge if that helps progress. Finish with
Code Listing 4.11: Completeing The System Set
emerge @system -uDN --keep-going --with-bdeps=y
Repeat the above command until it either finds nothing to do or completes with no errors.
Only you know what you need here. When you reboot, its a good idea to have keyboard support and
udev isn't going to load it for you any more.
Important: Review your lsmod to decide what you need
Getting ready to reboot
Making the Kernel
Follow the instructions at http://www.kernel-seeds.org which is mirrored at
http://kernel-seeds.grytpype-thynne.org with the following changes
Code Listing 5.1: Key Kernel Options
() path to uevent helper
[ ] Maintain a devtmpfs filesystem to mount at /dev
[ ] Unix98 PTY support
[*] Legacy (BSD) PTY support
(256) Maximum number of legacy PTY in use
Genkernel users are on their own here.
Making the Initrd
To make everything robust and independent of what filesystem gets attached to which/ dev node, we will use the filesystem UUIDs everywhere.
Warning: The kernel cannot mount root by UUID unless you use the userspace mount command, which requires and initramfs
There are several ways to make an initramfs, we will use the kernel provided usr/gen_init_cpio script.
The script needs two things, a list of files to include in the initramfs and an init sctipt to execute.
The use of usr/gen_init_cpio is well documented in the kernel.
Make a directory to hold the two files. I like /root/initrd. The two files that follow go there.
Code Listing 5.2: /root/initrd/initramfs_list
# directory structure
dir /proc 755 0 0
dir /usr 755 0 0
dir /bin 755 0 0
dir /sys 755 0 0
dir /var 755 0 0
#dir /lib 755 0 0
dir /lib64 755 0 0
dir /sbin 755 0 0
dir /mnt 755 0 0
dir /mnt/root 755 0 0
dir /etc 755 0 0
dir /root 700 0 0
dir /dev 755 0 0
dir /dev/mapper 755 0 0
# we have a static /dev so we need all dev entries too
# e.g. /dev/console below
nod /dev/console 0600 0 0 c 5 1
nod /dev/null 0666 0 0 c 1 5
# dev/sda and partitions
nod /dev/sda 0660 0 0 b 8 0
nod /dev/sda1 0660 0 0 b 8 1
nod /dev/sda2 0660 0 0 b 8 2
nod /dev/sda4 0660 0 0 b 8 4
nod /dev/sda5 0660 0 0 b 8 5
nod /dev/sda6 0660 0 0 b 8 6
# dev/sdb and partitions
nod /dev/sdb 0660 0 0 b 8 16
nod /dev/sdb1 0660 0 0 b 8 17
nod /dev/sdb2 0660 0 0 b 8 18
nod /dev/sdb4 0660 0 0 b 8 20
nod /dev/sdb5 0660 0 0 b 8 21
nod /dev/sdb6 0660 0 0 b 8 22
# dev/sdc and partitions
nod /dev/sdc 0660 0 0 b 8 32
nod /dev/sdc1 0660 0 0 b 8 33
nod /dev/sdc2 0660 0 0 b 8 34
nod /dev/sdc4 0660 0 0 b 8 36
nod /dev/sdc5 0660 0 0 b 8 37
nod /dev/sdc6 0660 0 0 b 8 38
# dev/sdd and partitions
nod /dev/sdd 0660 0 0 b 8 48
nod /dev/sdd1 0660 0 0 b 8 49
nod /dev/sdd2 0660 0 0 b 8 50
nod /dev/sdd4 0660 0 0 b 8 52
nod /dev/sdd5 0660 0 0 b 8 53
nod /dev/sdd6 0660 0 0 b 8 54
# dev/sdd and partitions the SSD
nod /dev/sde 0660 0 0 b 8 64
nod /dev/sde1 0660 0 0 b 8 65
nod /dev/sde2 0660 0 0 b 8 66
# the three raid nodes
nod /dev/md125 0660 0 0 b 9 125
nod /dev/md126 0660 0 0 b 9 126
nod /dev/md127 0660 0 0 b 9 127
# all the lvm nodes I need
nod /dev/dm-0 0660 0 0 b 253 0
nod /dev/dm-1 0660 0 0 b 253 1
nod /dev/dm-2 0660 0 0 b 254 2
nod /dev/dm-3 0660 0 0 b 254 3
nod /dev/dm-4 0660 0 0 b 254 4
nod /dev/dm-5 0660 0 0 b 254 5
nod /dev/dm-6 0660 0 0 b 253 6
nod /dev/dm-7 0660 0 0 b 253 7
nod /dev/dm-8 0660 0 0 b 254 8
nod /dev/dm-9 0660 0 0 b 254 9
nod /dev/dm-10 0660 0 0 b 254 10
nod /dev/dm-11 0660 0 0 b 254 11
nod /dev/dm-12 0660 0 0 b 253 12
nod /dev/dm-13 0660 0 0 b 253 13
nod /dev/dm-14 0660 0 0 b 254 14
nod /dev/dm-15 0660 0 0 b 254 15
nod /dev/dm-16 0660 0 0 b 254 16
nod /dev/dm-17 0660 0 0 b 254 17
nod /dev/dm-18 0660 0 0 b 254 18
slink /dev/stderr /proc/self/fd/2 777 0 0
slink /dev/stdin /proc/self/fd/0 777 0 0
slink /dev/std/out /proc/self/fd/1 777 0 0
file /bin/busybox /bin/busybox 755 0 0
# for raid on lvm
file /sbin/mdadm /sbin/mdadm 755 0 0
file /sbin/lvm.static /sbin/lvm.static 755 0 0
# libraries required by /sbin/fsck.ext4 and /sbin/fsck
slink /lib /lib64 777 0 0
file /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 755 0 0
file /lib64/libext2fs.so.2 /lib64/libext2fs.so.2 755 0 0
file /lib64/libcom_err.so.2 /lib64/libcom_err.so.2 755 0 0
file /lib64/libpthread.so.0 /lib64/libpthread.so.0 755 0 0
file /lib64/libblkid.so.1 /lib64/libblkid.so.1 755 0 0
file /lib64/libuuid.so.1 /lib64/libuuid.so.1 755 0 0
file /lib64/libe2p.so.2 /lib64/libe2p.so.2 755 0 0
file /lib64/libc.so.6 /lib64/libc.so.6 755 0 0
file /lib64/libmount.so.1 /lib64/libmount.so.1 755 0 0
file /sbin/fsck /sbin/fsck 755 0 0
file /sbin/fsck.ext4 /sbin/fsck.ext4 755 0 0
# our init script
file /init /root/initrd/init 755 0 0
I'm sure there is a sh one liner to feed to busybox mknod as a part of the init script, so I don't need the huge list of nod statements
but I don't know it.
If you use filessytems other than extX on /us/ and/ or /var, which the initrd checks and mounts,
you need your filesyatem tools listed here.
Feel free to add other things you find useful when booting fails too.
Code Listing 5.3: /root/initrd/init
echo "Something went wrong. Dropping you to a shell."
/bin/busybox --install -s
# allow the use of UUIDs or filesystem lables
for cmd in $(cat /proc/cmdline) ; do
case $cmd in
type=$(echo $cmd | cut -d= -f2)
echo "Mounting rootfs"
if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then
uuid=$(echo $cmd | cut -d= -f3)
mount -o ro $(findfs "$type"="$uuid") /mnt/root
mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root
# most of code coming from /etc/init.d/fsck
local fsck_opts= check_extra= RC_UNAME=$(uname -s)
# FIXME : get_bootparam forcefsck
if [ -e /forcefsck ]; then
echo "Checking local filesystem $check_extra : $1"
if [ "$RC_UNAME" = Linux ]; then
fsck_opts="$fsck_opts -C0 -T"
trap : INT QUIT
# using our own fsck, not the builtin one from busybox
/sbin/fsck -p $fsck_opts $1
case $ret_val in
0) return 0;;
1) echo "Filesystem repaired"; return 0;;
2|3) if [ "$RC_UNAME" = Linux ]; then
echo "Filesystem repaired, but reboot needed"
rescue_shell "Filesystem still have errors; manual fsck required"
4) if [ "$RC_UNAME" = Linux ]; then
rescue_shell "Fileystem errors left uncorrected, aborting"
echo "Filesystem repaired, but reboot needed"
8) echo "Operational error"; return 0;;
16) echo "Use or Syntax Error"; return 16;;
32) echo "fsck interrupted";;
127) echo "Shared Library Error"; sleep 20; return 0;;
*) echo $ret_val; echo "Some random fsck error - continuing anyway"; sleep 20; return 0;;
# rescue_shell can't find tty so its broken
# start for real here
# temporarily mount proc and sys
mount -t proc none /proc
mount -t sysfs none /sys
# assemble the raid set(s) - they got renumbered from md1, md5 and md6
# not needed on SSD but we may want to maintain it
/sbin/mdadm --assemble /dev/md125 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1
# don't care if /boot fails to assemble
# not needed on SSD
# / (root) I wimped out of root on lvm for this box
/sbin/mdadm --assemble /dev/md126 /dev/sda5 /dev/sdb5 /dev/sdc5 /dev/sdd5 || rescue_shell
# if root won't assemble, we are stuck
# LVM for everything else
# /home and everything portge related
/sbin/mdadm --assemble /dev/md127 /dev/sda6 /dev/sdb6 /dev/sdc6 /dev/sdd6 || rescue_shell
# and if the LVM space won't assemble there is no /usr or /var so we are really in a mess
# TODO could auto cope with degraded raid operation
# lvm runs as whatever its called as
ln -s /sbin/lvm.static /sbin/vgchange
# everything on the SDD
/sbin/vgchange -ay ssd || rescue_shell
# start the vg volume group - /home and everything for portage - need not die here
/sbin/vgchange -ay vg || rescue_shell
# get here with raid sets assembled and logical volumes available
# mounting rootfs on /mnt/root
uuidlabel_root || rescue_shell "Error with uuidlabel_root"
# space separated list of mountpoints that ...
# ... we want to find in /etc/fstab ...
ln -s /mnt/root/etc/fstab /etc/fstab
# ... to check filesystems and mount our devices.
for m in $mountpoints ; do
echo "Mounting $m"
# mount the device and ...
mount $m || rescue_shell "Error while mounting $m"
# ... move the tree to its final location
mount --move $m "/mnt/root"$m || rescue_shell "Error while moving $m"
echo "All done. Switching to real root."
# clean up. The init process will remount proc sys and dev later
# switch to the real root and execute init
exec switch_root /mnt/root /sbin/init
Run blkid to discover the UUIDs of all your block devices. Paste the output into /etc/fstab, so its easy to refer to in the future.
Delete lines that provide the UUIDS of block devices that are not filesystesms, e.g. lvm members, md devices.
Comment out the other entries, so they can stay in the file.
Populating /etc/fstab as normal, but use UUIDs as in
Code Listing 5.4: Example /etc/fstab
UUID=741183c2-1392-4022-a1d3-d0af8ba4a2a8 /boot ext2 noauto,noatime 1 2
UUID=bcd0b621-2027-4471-ac26-99c5f95ee2d3 / ext4 noatime,discard 0 1
UUID=0f7610bd-67c9-40c6-8a16-70d617ef09d3 /var ext4 noatime,noauto,discard 1 0
UUID=3e82328c-e85f-435e-8836-5c63b38df620 /usr ext4 noatime,noauto,discard 1 0
but use your UUIDs, your mount points and your mount options.
As there is no auto mounting, don't forget entries for optical drives.
Floppy disk users need to remember /dev/fdX and friends.
Configuring your System
Follow Gentoo Handbook Chapter 8.
Installing Necessary System Tools
Follow Gentoo Handbook Chapter 9.
Setting up the Boot Loader
The Grand Unifided Bootloadre, grub, has already been installed to /boot
Follow Gentoo Handbook Chapter 10. to install
grub to the Master Boot Record and create a /boot/grub/grub.conf file
Linux Sea offers a gentle yet technical (from end-user perspective) introduction to the Linux operating system, using Gentoo Linux as the example Linux distribution.
Link included with permission from the author.
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.