Still reading ... don't say you were never warned. The usual caveat applies, if it breaks, you can keep the pieces. You might even try a post in Unsupported Software on the Gentoo Forums.
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:-
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 Gentooee is more about what you don't get. You dont get
Separate /usr should just work as there is no udev to require that /usr is mounted before udev starts. If udev starts on your box you have done someting wrong. Separate /usr is not tested as I'm using lvm on top of raid5, so while my /usr is separate, bad habits have made me mount it in the initrd.
Access to the
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
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.
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 Gentooee
mkdir -p /mnt/gentoo/etc/portage 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
nano -w /mnt/gentoo/etc/locale.gen
Make mountpoints for special filesystems and other directories that would have been provided by the stage 3.
mkdir /mnt/gentoo/dev mkdir /mnt/gentoo/proc mkdir /mnt/gentoo/home mkdir /mnt/gentoo/var mkdir /mnt/gentoo/var/log mkdir /mnt/gentoo/tmp mkdir /mnt/gentoo/sys mkdir /mnt/gentoo/boot
Change the permissions on /mnt/gentoo/tmp to 1777
Portage needs some workspace in the chroot with a special mode set.
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.
Its quite safe to bind mount /usr/portage and /usr/portage/distfiles inside the chroot, 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.
eselect profile won't work yet, so make the make.profile symlink by hand, just like in the good old days.
cd /mnt/gentoo/etc 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. A static busybox is always a good idea but its not actually required until you break glibc.
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.
We need the latest python-2.x and the latest python-3.x so the list contains two entries for python.
cd /usr/portage/packages tar xpf app-shells/bash-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-lang/python-2.<ver>.tbz2 -C /mnt/gentoo tar xpf dev-lang/python-3.<ver>.tbz2 -C /mnt/gentoo 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-<ver>.tbz2 -C /mnt/gentoo tar xpf app-admin/eselect-<ver>.tbz2 -C /mnt/gentoo tar xpf app sys-devel/gcc-config-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-devel/gcc-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-apps/sandbox-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-libs/readline-<ver>.tbz2 -C /mnt/gentoo tar xpf virtual/libc-<ver>.tbz2 -C /mnt/gentoo tar xpf app-arch/xz-utils-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-apps/grep-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-libs/libpcre-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-devel/patch-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-apps/openrc-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-libs/pam-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-apps/gawk-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-libs/mpc-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-libs/mpfr-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-libs/gmp-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-devel/binutils-<ver>.tbz2 -C /mnt/gentoo tar xpf app-text/iso-codes-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-kernel/linux-headers-<ver>.tbz2 -C /mnt/gentoo tar xpf sys-apps/diffutils-<ver>.tbz2 -C /mnt/gentoo tar xpf app-misc/pax-utils-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-util/pkgconfig-<ver>.tbz2 -C /mnt/gentoo tar xpf dev-libs/glib-<ver>.tbz2 -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 ln -s /bin/bash /bin/sh ln -s /usr/bin/gawk /bin/awk ln -s /usr/bin/gmake /usr/bin/make ln -s /usr/x86_64-pc-linux-gnu/binutils-bin/<ver>/ar /usr/bin/ar ln -s /usr/x86_64-pc-linux-gnu/binutils-bin/<ver>/as /usr/bin/as ln -s /usr/x86_64-pc-linux-gnu/binutils-bin/<ver>/ld /usr/bin/ld ln -s /usr/x86_64-pc-linux-gnu/binutils-bin/<ver>/nm /usr/bin/nm
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.
mount -t proc proc /mnt/gentoo/proc
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
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
env-update source /etc/profile 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
set hostname
This is important. Enter the package atoms that you do not want to see installed ever.
# go back to a static /dev sys-fs/eudev sys-fs/udev sys-auth/polkit sys-auth/consolekit media-sound/pulseaudio sys-apps/systemd
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.
This section is only required if you use raid, or lvm. You will need some packages built with the static USE flag.
# static bits and pieces for an initrd sys-fs/lvm2 static sys-fs/mdadm static sys-apps/busybox static # to keep perl users happy dev-lang/perl -build
Some of my USE flags are AMD specific. The flags that are set off here are for avoidance of optional support for packages we have already masked. Optional support being on would attempt to pull those packages in and emerge would complian about masked packages.
USE="3dnow 3dnowext X alsa device-mapper apng mmx mmxext mp3 python sse sse2 jpeg lock session startup-notification thunar curl ffmpeg odf pdf raw gtk cairo -consolekit -dso -firmware-loader -gbm -kmod -ldap -networkmanager -nss -oss -qt4 -tools -udev -zeroconf"
-zeroconfig is a special case. Zeroconfig wasn't around 10 years ago so really should be excluded here.
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 in IUSE. Make a local overlay called static_dev, copy these ebuilds there and remove all references to udev.
git clone git@weaver.gentooexperimental.org:gentoo-static.git gentoo-static
Emerging static-dev
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 static-dev is emerged.
emerge static-dev
is installed
static-dev is a good start but its not moved on in a very long time. Add some of the newer entries required. See /usr/src/linux/Documentation/devices.txt for a list
Don't forget nodes for removable storage devices.
lvm2 insists on udev lsusb builds but gives unable to initialize libusb: -99
DRI users, that's almost everone except those who use nvidia-drivers for Xorg will need to make /dev/dri/*. What is needed here is driver dependent.
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 with portage
emerge @system --keep-going --with-bdeps=y
Add --nodeps to the above emerge if that helps progress. Finish with
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.
Follow the instructions at http://www.kernel-seeds.org which is mirrored at http://kernel-seeds.grytpype-thynne.org with the following changes
() 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 [ ] Dynamic device file minor numbers
Genkernel users are on their own here.
To make everything robust and independent of what filesystem gets attached to which/ dev node, we will use the filesystem UUIDs everywhere.
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.
# 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 # busybox 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 /usr and/ or /var, which the initrd checks and mounts, you need your filesystem tools listed here. Feel free to add other things you find useful when booting fails too.
#!/bin/busybox sh rescue_shell() { echo "$@" echo "Something went wrong. Dropping you to a shell." /bin/busybox --install -s exec /bin/sh } # allow the use of UUIDs or filesystem lables uuidlabel_root() { for cmd in $(cat /proc/cmdline) ; do case $cmd in root=*) 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 else mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root fi ;; esac done } check_filesystem() { # 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 fsck_opts="$fsck_opts -f" check_extra="(check forced)" fi echo "Checking local filesystem $check_extra : $1" if [ "$RC_UNAME" = Linux ]; then fsck_opts="$fsck_opts -C0 -T" fi trap : INT QUIT # using our own fsck, not the builtin one from busybox /sbin/fsck -p $fsck_opts $1 ret_val=$? 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" reboot -f else rescue_shell "Filesystem still have errors; manual fsck required" fi;; 4) if [ "$RC_UNAME" = Linux ]; then rescue_shell "Fileystem errors left uncorrected, aborting" else echo "Filesystem repaired, but reboot needed" reboot fi;; 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;; esac # rescue_shell can't find tty so its broken rescue_shell } # 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 # /boot /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 ... mountpoints="/usr /var" # ... 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 $m check_filesystem $m 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" done echo "All done. Switching to real root." # clean up. The init process will remount proc sys and dev later umount /proc umount /sys # switch to the real root and execute init exec switch_root /mnt/root /sbin/init
Now to feed the /root/initrd/initramfs_list file to usr/gen_init_cpio. Make sure /boot is mounted
cd /usr/src/linux usr/gen_init_cpio /root/initrd/initramfs_list > /boot/initramfs_static
This what the kernel build system does if you choose to build the initramfs into the kernel binary but if you don't get it right first time, you can fix your kernel without rebuilding your initramfs and vice versa.
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
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. Users who have not formatted a floppy with a static /dev are in for a treat.
Follow
Follow
The Grand Unifided Bootloader, grub, has already been installed to /boot
Follow
You need a whole xorg.conf, just like in the good/bad old days.
Most modern terminal emulators want to use /dev/pts for pseudo terminals. Thats not an option here. Use rxvt, which seems to justwork
Gnome is not an option. I suspect that KDE is out too.
Xfrce almost works out of the box. Its terminal emulator wants /dev/pts, so use rxvt, or anything else that works with the BSD style ptys.
Link included with permission from the author.