Install Gentoo on a bootable USB stick

From Gentoo Wiki
Jump to: navigation, search

Booting Gentoo from a USB stick is really quite simple, to make it work properly though you need to setup an initial ramdisk and you will need to make sure you have drivers for all the machines you are going to boot with it. This article will describe how to install Gentoo onto a USB stick that can be booted in any computer. This installation will be just like your desktop installation and changes will be persistent.

Preparation

Before one begins, some packages are needed. It is assumed that you are running on a Gentoo system to create this bootable USB stick. Most importantly a kernel and the sys-kernel/genkernel package are needed.

root # emerge --ask sys-kernel/gentoo-sources sys-kernel/genkernel

To add package-specific useflags, you may need to make a new file in /etc/portage/package.use/:

File/etc/portage/package.use/sys-apps

sys-apps/busybox static
root # emerge --ask sys-apps/busybox

Compile the kernel

Make the required changes to your kernel and compile it. Please see section 7 of the handbook and Kernel/Configuration for more detail on this step. Importantly remember that a general kernel is better here because the more general it is the more machines will boot with it. You can still compile modules as these will be included in the initramfs and loaded at boot.

root # mkdir /tmp/boot
genkernel --firmware --busybox --disklabel --bootdir=/tmp/boot --no-symlink --all-ramdisk-modules --install all

The above command will take some time as it will build the default kernel and create a ramdisk then copy them into /tmp/boot.

root # ls /tmp/boot/
initramfs-genkernel-x86_64-3.5.2-gentoo
kernel-genkernel-x86_64-3.5.2-gentoo
System.map-genkernel-x86_64-3.5.2-gentoo

Prepare the USB stick

Create 2 partitions on the drive (you can probably do it with one but it is normal practice to create a /boot and a / (root) partition. It is assumed that your USB stick is /dev/sdb. The USB stick could also be /dev/sdc. If you run dmesg immediately after you plug in the USB Stick you should see a message which shows the device letter.
root # dmesg|tail
Adjust as necessary.


root # fdisk /dev/sdb
Command (m for help): d
Selected partition 1

Command (m for help): n
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-4001759, default 2048): 
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-4001759, default 4001759): +100M

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2):  
Using default value 2
First sector (206848-4001759, default 206848): 
Using default value 206848
Last sector, +sectors or +size{K,M,G} (206848-4001759, default 4001759): 
Using default value 4001759

Command (m for help): a
Partition number (1-4): 1

Command (m for help): p

Disk /dev/sdb: 2048 MB, 2048901120 bytes
255 heads, 63 sectors/track, 249 cylinders, total 4001760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x001663df

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        2048      206847      102400   83  Linux
/dev/sdb2          206848     4001759     1897456   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

Make sure that the first partition is bootable (a command toggles the boot flag).

Now format the new partitions to the ext2 file system (but you can use another file system for the / partition if it has support in your kernel). Notice that we have given the drives a label, this is important because it will be how we detect the root file system later, you also notice --disklabel on the genkernel command line earlier.

root # mkfs.ext2 -L GENTOO_USB_BOOT /dev/sdb1
root #
mkfs.ext2 -L GENTOO_USB_ROOT /dev/sdb2

Stage 3 installation

The kernel is ready, the initial ramdisk is ready and our file systems have been created and labelled, now we need some shell utilities and such. This is all contained in the stage3 tarball available from your nearest Gentoo mirror... and portage snapshot.

For this example stage3-amd64-20120621.tar.bz2 and portage-latest.tar.xz were downloaded. This next bit is the same as in the handbook for installing Gentoo.

root # mount /dev/sdb2 /mnt/gentoo
root #
cd /mnt/gentoo
root #
tar -xpf ~/Download/stage3-amd64-20120621.tar.bz2
root #
cd usr
root #
tar -xpf ~/Download/portage-latest.tar.xz
root #
mount /dev/sdb1 /mnt/gentoo/boot
root #
cp /tmp/boot/* /mnt/gentoo/boot

Chrooting

Now we are going to chroot into the Gentoo environment...

root # mount -t proc none /mnt/gentoo/proc
root #
mount --rbind /dev /mnt/gentoo/dev
root #
mount --rbind /sys /mnt/gentoo/sys
root #
cp /etc/resolv.conf /mnt/gentoo/etc/resolv.conf
root #
chroot /mnt/gentoo /bin/bash

Bootloader

So that you can boot the new system you must install a bootloader onto your USB stick. You have many options for this, but here I will just run through lilo and syslinux.

lilo Bootloader Configuration

Emerge lilo.

root # emerge sys-boot/lilo

Edit etc/lilo.conf so that it has the correct information in it now.

Warning
These settings are very important and will be discussed line by line. If you get this wrong you might break your current Linux installation.
File/etc/lilo.confConfigure lilo.conf

boot=/dev/sdb              # The location of your USB Stick
lba32                      # use lba32 addressing (ignore)
compact                    # boot quickly by loading lots of blocks
                           # remove if you have problems booting
prompt                     # Prompt for user input
timeout=20                 # Time to wait before default selection
default="Gentoo-352"       # Default selection after timeout

image=/boot/kernel-genkernel-x86_64-3.5.2-gentoo
	label="Gentoo-352"
	read-only
	root=/dev/ram0
	append="real_root=LABEL=GENTOO_USB_ROOT scandelay=5"
	initrd=/boot/initramfs-genkernel-x86_64-3.5.2-gentoo

The lines after image are all easy but the append line contains some interesting options. REAL_ROOT=LABEL=GENTOO_USB_ROOT will use the label of the disk instead of /dev/sdb2 which is important because these device numbers move around depending on the number of hard disks in the computer or number of USB disk drives. Also important for USB booting is the scandelay, as USB devices need a little time to be detected by the kernel; that is what this option is for. When you have lots of modules booting takes a long time so it probably does not matter, but if you have only a few it is important, because the system could have booted before the kernel detects the USB device. Also, on newer machines with USB3 controllers you will need the xhci_hcd driver (built into the kernel or as a module).

root # lilo
gentoohost boot # lilo
Warning: /dev/sdb is not on the first disk
Warning: The initial RAM disk is too big to fit between the kernel and
   the 15M-16M memory hole.  It will be loaded in the highest memory as
   though the configuration file specified "large-memory" and it will
   be assumed that the BIOS supports memory moves above 16M.
Added Gentoo-352 ? *
2 warnings were issued.

The first warning is to be expected as we are not installing the boot loader onto the hard disk in your computer. The second warning will only cause a problem on machines that are old, if it is a problem for you try cutting down the kernel by removing modules.

syslinux Bootloader Configuration

Warning
syslinux works with ext{2,3,4}, btrfs, ntfs and fat filesystems.
root # emerge syslinux

Put the boot sector onto your USB stick.

root # dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sdb

Now to configure the bootloader, to do this we use a text editor:

root # mkdir /boot/syslinux
File/boot/syslinux/syslinux.cfg

PROMPT 1
TIMEOUT 50
DEFAULT gentoo
 
LABEL gentoo
        LINUX ../kernel-genkernel-x86_64-3.5.2-gentoo
        APPEND root=LABEL=GENTOO_USB_ROOT scandelay=3 ro
        INITRD ../initramfs-genkernel-x86_64-3.5.2-gentoo
Note
The "ro" in the above APPEND line will cause the root partition to be mounted read-only. If you want (read-write) to be able to make changes to the system while booted from the USB stick, replace "ro" with "rw".

Then to install syslinux onto your USB stick, device is not absolutely necessary but will throw an error if you make a mistake (not that we ever make mistakes ;-) ).

root # extlinux --device /dev/sdb1 --install /boot/syslinux

fstab Configuration

File/etc/fstabConfigure your fstab to work with labels

LABEL=GENTOO_USB_BOOT   /boot           ext2            noauto,noatime  1 2
LABEL=GENTOO_USB_ROOT   /               ext2            noatime         0 1
/dev/SWAP               none            swap            sw              0 0
/dev/cdrom              /mnt/cdrom      auto            noauto,ro       0 0
/dev/fd0                /mnt/floppy     auto            noauto          0 0

Set the password for the root user and that is it. Exit the chroot environment and unmount all the mounts you made before going into it.

Setting the root password

The stage3 tarball we used comes with a password... I don't now what that password is and you should change it anyway, before leaving your chroot make sure to set it to something you know so that you can login to your new system.

root # passwd

Locale and other configurations

The locale configuration is left up to you, it is quite easy and covered in the handbook. But don't skip this step!

Little tips

Although you can use the system we just made as a standard Gentoo system, if you are using a USB stick rather than a hard drive it might be worthwhile compiling binary packages on a host and then installing then pulling them on in binary form... or if you have enough memory just mount /var/tmp to a tmpfs, as compilation will be quicker that way anyway!

That is all

You should now be able to boot your shiny new Gentoo system from the USB drive.

Note
Although an amd64 system was used here to do this, it will work just the same way for a 32-bit x86 machine.