TinyGentoo
From Gentoo Linux Wiki
| Terminals / Shells • Network • X Window System • Portage • System • Filesystems • Kernel • Other |
Contents |
[edit] What is this?
I've got a 64MB USB flash disk, and I wanted Gentoo on it, but to still have plenty of room for other files. Because there wasn't anything already out there, I figured it out for myself, and this is pretty much a HOWTO make a Tiny Gentoo (under 5MB) using uClibc and busybox (what the embedded guys use). Links to other (larger) projects and pages that were very helpful for me are at the See Also section.
[edit] What you need
- USB flash disk or flash card (min. 8MB)
- About 500MB free on your HDD (depends on how you decide to go on about things)
- A motherboard/laptop that supports booting from a USB flash disk
- Some free time
[edit] Getting started
Choose a mirror close to you ( http://www.gentoo.org/main/en/mirrors.xml ), then hop into experimental/x86/embedded/stages, if your arch is x86. Download the stage3 file or stage1 or 2 if you want to play around more than what is necessary.
Feel free to be creative with the file and folder names, I'm just using ones that will explain what they are for. Basically we're just following the Gentoo Handbook Chapter 5, but with a few differences, most of the stuff we don't need to do because we'll only be chrooting into it.
A more detailed guide for creating the chroot can be found here.
[edit] Entering the chroot
mkdir /mnt/gentoo_uclibc cd /mnt/gentoo_uclibc mv <path to>/stage* . tar xjpf stage*.tar.bz2 cp -L /etc/resolv.conf etc/resolv.conf mkdir -p usr/portage
And what you'll need to repeat every time when entering the chroot:
mount --bind /usr/portage /mnt/gentoo_uclibc/usr/portage mount --bind /dev /mnt/gentoo_uclibc/dev mount -t proc proc /mnt/gentoo_uclibc/proc chroot /mnt/gentoo_uclibc/ /bin/bash env-update && source /etc/profile
tar xjf <path to>/portage-<timestamp>.tar.bz2 -C /mnt/gentoo_uclibc/usr
[edit] Basic setup inside the chroot
We do want all the symlinks for busybox, and ccache, and only minimal versions of packages that support that use flag.
| File: /etc/make.conf |
# To use previously built packages, use the -k option with emerge
FEATURES="ccache buildpkg"
USE="minimal"
# Store .tbz2's in their own directory
PKGDIR="${PORTDIR}/packages/uclibc"
|
The uclibc stages on the mirrors are quite old, so you will need to change the profile to a newer version. Emerge ccache first so that portage can use it for all the other packages. Then update all the packages, emerge the 2.6 kernel sources and copy the default bash login scripts to root's home directory.
# ln -snf /usr/portage/profiles/uclibc/x86 /etc/make.profile # emerge ccache # emerge -au portage # emerge -auDN world # emerge vanilla-sources # cp /etc/skel/.bash_profile /etc/skel/.bashrc /root/ # mkdir /tinygentoo
If you get sandbox violation errors when upgrading coreutils just do
FEATURES="-sandbox" emerge coreutils
If you get errors while running the ancient emerge against the new portage tree use the following work-around:
On your parent Gentoo system create a package containing a working portage:
# quickpkg --include-config=y portage
You now have a package file at '/usr/portage/packages/All/portage-#.#.#.#.tbz2'. Chroot back into the subsystem as explained above and type 'cd /' to go to the root. Now extract the working portage over the embedded system chroot by typing:
# tar xvjf /usr/portage/packages/All/portage-#.#.#.#.tbz2
Finally you should emerge portage itself using the new emerge (from the parent system) to make sure everything is fine: 'emerge portage'
If sys-apps/gawk fails, see Bug #195368. Copy /usr/include/netdb.h to /usr/include/netdb.h.orig. Then add the following after line 403 in netdb.h:
| File: /usr/include/netdb.h |
# define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */ # define AI_ALL 0x0010 /* Return IPv4 mapped and IPv6 addresses. */ # define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose returned address type. */ |
After a successful emerge world you may want to emerge app-portage/gentoolkit and run revdep-rebuild. If this fails because it wants to emerge an old python that is no longer supported(?), try emerge -pv python to find out which version you have, and then unemerge all old versions by using emerge -C '<python-X.Y.Z'. Replace X.Y.Z by the version you have, and don't forget the single quotes to prevent misinterpretation of the '<' sign by the shell. After this, do rm /root/.revdep* and try the revdep-rebuild again.
If the emerge -auDN world fails on busybox, then first emerge uclibc, then retry emerging world.
If after the above sys-apps/busybox fails with error: '__NR_clock_gettime' undeclared you need to upgrade sys-libs/uclibc. For the current version (1.8.2 as well as 1.7.4) uclibc-0.9.29 is needed, which is not in portage. See Bug #182094 for updated ebuilds.
Alternatively, to work around the busybox problem, you can do the following
FEATURES="keepwork" emerge busybox # this will fail with the __NR_clock_gettime error cd /var/tmp/portage/sys-apps/busybox-1.x.y/work/busybox-1.x.y make menuconfig Deselect "BusyBox Settings"->"BusyBox Library Tuning"->"Use Clock Gettime" Exit configuration mkdir -p /etc/portage/savedconfigs/sys-apps/busybox cp .config /etc/portage/savedconfigs/sys-apps/busybox cd $HOME USE="savedconfig" emerge busybox
[edit] /tinygentoo
Everything that will finally be turned into an initramfs will be in /tinygentoo/. Using ROOT=/tinygentoo before emerge commands will emerge the packages into that directory. This way you do not need portage or gcc in there, but only the packages you really want.
[edit] Basic setup of /tinygentoo
[edit] Emerge the base packages
Emerge lines that do not have ROOT=/tinygentoo will be installed into the chroot so that it will be able to compile the other packages without errors. We do not add symlink to /etc/make.conf because that would interfere with later updating the baselayout-2, which will need to be unmasked first. See emerge --help if you're not sure what the options used do. Please note that at the time of writing, baselayout 2.0.0 is the most recent version. You can choose to unmask newer versions (and their dependencies) when needed.
mkdir -p /etc/portage echo "=sys-apps/baselayout-2.0.0 **" >> /etc/portage/package.keywords echo "=sys-apps/openrc-0.2.1-r1 **" >> /etc/portage/package.keywords echo "=sys-fs/udev-118-r2 **" >> /etc/portage/package.keywords echo "=sys-apps/baselayout-2.0.0" >> /etc/portage/package.unmask echo "=sys-apps/openrc-0.2.1-r1" >> /etc/portage/package.unmask ROOT=/tinygentoo USE=symlink emerge -avkN =sys-apps/baselayout-2.0.0 uclibc busybox
[edit] Setting up users
chroot into /tinygentoo/ and change the root password.
Please note, the shell shipped with busybox is /bin/ash, not /bin/bash:
chroot /tinygentoo /bin/ash passwd
Add a regular user. Change foo to your username:
addgroup -g 100 users adduser -h /home/foo -s /bin/ash -G users foo
exit the /tinygentoo chroot:
exit
[edit] Set the hostname
Replace TinyGentoo if you would like to use some other hostname. /etc/hostname is read by /sbin/init, see /tinygentoo/etc/inittab. echo "TinyGentoo" > /tinygentoo/etc/hostname.
[edit] Writing fstab
The root filesystem will be mounted as ramfs by the kernel. The only downside to this is that unlike tmpfs it does not have a size limit, so writing a lot to / could fill up your ram. Anything that is on tmpfs uses nearly no ram when empty and grows when needed but wont use up all of the ram, leaving room for applications to run.
Feel free to be creative, just remember that flash doesnt like being written to lots and lots, so do not mount / or /var onto it. sda1 is the partiton on the USB stick that will contain the bootloader files, the kernel and the initrd. /dev/sda2 will be the partition that you see when in windows, and you can use it to store any settings/files from TinyGentoo too.
| File: /tinygentoo/etc/fstab |
none /tmp tmpfs defaults 0 0 none /proc proc defaults 0 0 /dev/sda1 /boot ext2 noauto,ro 0 0 /dev/sda2 /mnt/dongle vfat defaults 0 0 |
Make the two directories that do not yet exist mkdir /tinygentoo/boot /tinygentoo/mnt/dongle
[edit] Writing /init
This step is optional. Instead of having this file you could add init=/sbin/init to the grub kernel line.
/init is the file that the kernel executes right after loading the content of the initramfs. If you are using initrd instead of initramfs, rename this file to linuxrc
| File: /tinygentoo/init |
#!/bin/ash echo echo echo " Welcome to TinyGentoo." echo echo echo " * Setting umask.." umask 022 echo " * Mounting /proc.." mount -t proc none /proc echo " * Starting init.." exec <dev/console >dev/console 2>&1 exec chroot . /sbin/init echo " *** Starting init failed! ***" echo " * Trying to start a shell.." exec /bin/ash |
Remember to make it executable chmod +x /tinygentoo/init
If you would like to be able to use the same script with both initrd or initramfs, you can symlink one /init to /linuxrc.
cd /tinygentoo ln -s init linuxrc
Optional, but if you would like to change the timezone, edit /tinygentoo/etc/TZ. For example, echo UTC > /tinygentoo/etc/TZ.
[edit] Emerging the wanted packages into /tinygentoo
Choose what packages you want. esearch foo in your regular Gentoo to easily find out what the packages are. The examples will provide you with an installation that can browse the web (lynx), connect to IRC (scrollz), run and connect to SSH servers (dropbear) and screen, that I don't know how some people live without.
ROOT=/tinygentoo emerge -avk lynx scrollz dropbear screen
That's it for /tinygentoo. chroot back in if you want to get a feel for it.
You have to set this before you try to emerge coreutils:
export gl_cv_func_getcwd_path_max=yes
[edit] Kernel
In theory you could just use a kernel built outside the uClibc chroot, but that would get confusing.
[edit] Kernel configuration
Not very hard really, and because we will be using an initramfs image most things can be compiled as modules if you wish to do so. Disable everything that you don't want or need to keep the size of the kernel image down.
cd /usr/src/linux make menuconfig
make menuconfig SUBARCH=i386
| Linux Kernel Configuration: vanilla-sources-2.6.16 for TinyGentoo |
Code maturity level options ---> [*] Prompt for development and/or incomplete code/drivers General setup ---> [*] Enable 16-bit UID system calls [*] Optimize for size [*] Configure standard kernel features (for small systems) ---> Note: if you are using uClibc 0.9.28 or older, you need to enable 16bit UID interfaces in the Linux kernel. This has been fixed in svn so newer uclibc's will use the 32 bit interfaces. You don't want HIGHMEM if you haven't 1G or more RAM. Processor type and features ---> (4GB) High Memory Support [*] MTRR (Memory Type Range Register) support [ ] Symmetric multi-processing support Enable this if you want normal hard disk support Device Drivers ---> ATA/IDE/MFM/RLL support ---> < > ATA/IDE/MFM/RLL support What we need for reading from the USB stick to work: SCSI support ---> <*> SCSI support <*> SCSI disk support Of course we need the following because we run with an initrd root filesystem: Block devices ---> <*> RAM disk support (16) Default number of RAM disks (4096) Default RAM disk size (kbytes) [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support For networking remember to select the driver for the chipset of your NIC. Use lspci to find out what you've got. I have on-board nForce2 and some cheap PCI card with an RTL-8139 chip. Network device support --->
< > Dummy net driver support
Ethernet (10 or 100Mbit) --->
[*] Ethernet (10 or 100Mbit)
[*] EISA, VLB, PCI and on board controllers
<m> nForce Ethernet support (EXPERIMENTAL)
<m> RealTek RTL-8139 PCI Fast Ethernet Adapter support
Keyboard support might be nice: Input device support ---> [*] Keyboards 'Cos we'd like to be able to actually do something (enabled and hidden by default if CONFIG_EMBEDDED is not set): Character devices ---> [*] Virtual terminal [*] Support for console on virtual terminal [*] Unix98 PTY support We don't want X stuff: < > /dev/agpgart (AGP Support) < > Direct Rendering Manager Use lspci -v | grep HCI to see what ?HCI drivers you want. lspci is part of sys-apps/pciutils USB support ---> <*> Support for USB <*> EHCI HCD (USB 2.0) support (EXPERIMENTAL) <*> UHCI Alternate Driver (JE) support <*> OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support <*> USB Mass Storage support For rw access to a partiton on the USB stick that is accessable from Windows too select VFAT. File systems ---> <M> DOS FAT fs support <M> VFAT (Windows-95) fs support [*] /proc file system support Native Language Support ---> <*> NLS ISO 8859-1 (Latin 1; Western European Languages) (NEW) Console drivers ---> [*] VGA text console [*] Video mode selection support |
As a final touch, you may also need something else than the default us keymap for your future system. If you need it, you can build the proper keymap for your keyboard layout inside the kernel issuing the following command from within the /usr/src/linux directory:
loadkeys -m <path_to_keymap> > drivers/char/defkeymap.c
An example for french layout:
loadkeys -m /usr/share/keymaps/i386/azerty/fr.map.gz > drivers/char/defkeymap.c
[edit] Compiling the kernel
Now just:
make -j2 && make modules_install cp arch/i386/boot/bzImage /tmp/vmlinuz-tinygentoo
If you go back to menuconfig and change things, clean out the old modules so there wont be any extra ones taking up space:
rm -r /lib/modules/* make modules_install
or if you don't want do the next step (coping modules) you can launch this command:
make INSTALL_MOD_PATH=/tinygentoo modules_install
[edit] Copying the modules
We want all the modules inside the initrd, so they'll need to be copied there.
mkdir -p /tinygentoo/lib/modules cp -vr /lib/modules/* /tinygentoo/lib/modules/
[edit] Packaging /tinygentoo
We want everything under /tinygentoo to be turned into a single initramfs image. Don't forget to copy the kernel modules to /tinygentoo before this step!
[edit] Cleaning up
Copy the files to some other place so you can easily restart if you mess up, then remove all the files you don't need or want.
cp -r /tinygentoo /tmp/ rm -r /tmp/tinygentoo/var/*/* /tmp/tinygentoo/tmp/*
If you want to see how much space its using:
du -hs /tmp/tinygentoo
[edit] Creating the initramfs image
To create the initramfs image we will use cpio to create an archive of the files that the kernel can understand, and gzip it to make it smaller.
cd /tmp/tinygentoo && find . | cpio -H newc -o | gzip -9 > /tmp/initramfs-tinygentoo.igz
[edit] Preparing the USB flash disk
Basically we just want one partiton for the TinyGentoo boot files, and one partiton for saving files that you want to keep even after a reboot, and that will also be accessable from Windows.
[edit] Backing up the old data
Just in case you don't like it or just want to try it or.... something else, back up what you have got on your dongle (USB flash disk) right now. Make sure that you use the correct device, it might not be /dev/sda if you have other drives showing up as SCSI. Those could be a SATA hdd, a camera or an MP3 player. fdisk -l will show you what partitions are seen by linux.
Preferably do all the partitioning stuff outside the uClibc chroot, but you could do it from in there too if you've fallen in love with it :P
We'll just raw copy the whole disk. Note: sda is the whole disk, sda1 is only the first partition, it does not include the MBR/partiton table. Gzip it too to save space. 4K blocks to read to make it slightly faster, but its still slow..
cd /root dd if=/dev/sda of=dongle_backup.img bs=4K gzip dongle_backup.img
[edit] Creating the partitions
Clear the partition table and use fdisk (or something else if you don't like fdisk) to create the partitions.
dd if=/dev/zero of=/dev/sda bs=1 count=512 fdisk /dev/sda
Change the size of the boot partition so that it will fit your kernel + initrd.img + 1-2MB, though you could make it larger if you would like to use it for other stuff too.
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1024, default 1): <enter> Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-1024, default 1024): +6M
To make it bootable:
Command (m for help): a Partition number (1-4): 1
Then the vfat partition. Your cylinder numbers propably will not match mine, don't worry bout that.
Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (95-1024, default 95): <enter> Last cylinder or +size or +sizeM or +sizeK (95-1024, default 1024): <enter> Using default value 1024
Change the type to FAT32 so that Windows will see it correctly
Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): b Changed system type of partition 2 to b (W95 FAT32)
Then to check everything is OK
Command (m for help): p
If yes, write and exit
Command (m for help): w
[edit] Formatting the partitions
There isn't really any good reason to use something other than ext2 for the boot partition. You may need to emerge dosfstools for vfat formatting support. The -F 32 makes it FAT32 to support longer filenames and stuff. Change label to what name you would like the partition to have.
mke2fs /dev/sda1 mkfs.vfat -v -F 32 -n label /dev/sda2
[edit] Installing GRUB
If you do not yet have grub, mount /boot && emerge grub.
First you will need to copy the stages. e2fs_stage1_5 is optional, and you may delete it after grub has embedded it. Make sure you have /boot mounted to be able to copy the files from there.
mkdir /mnt/dongle mount /dev/sda1 /mnt/dongle mkdir /mnt/dongle/grub cp /boot/grub/stage? /boot/grub/e2fs_stage1_5 /mnt/dongle/grub/ umount /mnt/dongle grub grub> device (hd0) /dev/sda grub> root (hd0,0) grub> setup (hd0) grub> quit mount /dev/sda1 /mnt/dongle rm /mnt/dongle/grub/e2fs_stage1_5
[edit] Alternative
In my case, I had to do use the following commands.
mkdir /mnt/dongle mount /dev/sda1 /mnt/dongle mkdir /mnt/dongle/grub cp /boot/grub/stage? /boot/grub/e2fs_stage1_5 /mnt/dongle/grub/ touch /mnt/dongle/grub/usb_flag umount /mnt/dongle grub grub> find /grub/usb_flag (hd1,0) grub> root (hd1,0) grub> setup (hd1) grub> setup (hd1,0) grub> quit mount /dev/sda1 /mnt/dongle rm /mnt/dongle/grub/usb_flag
The difference being that I had to setup BOTH the MBR and the boot partition's MBR. Until I did this, my BIOS would not boot from the USB stick.
[edit] Writing menu.lst (for GRUB)
GRUB looks for menu.lst, not grub.conf, but you may make a symlink to grub.conf from menu.lst and then edit grub.conf.
Add init=/sbin/init to the kernel line if you do not have a linuxrc file.
| File: /mnt/dongle/grub/menu.lst |
timeout 3 title TinyGentoo kernel /vmlinuz-tinygentoo vga=791 initrd /initramfs-tinygentoo.igz |
Set vga=ask to get a prompt to be able to select the resolution for your console. With the ramdisk_size= option you can set how large you would like your / to be, in KB. Don't set it too high if because you will also need RAM for applications to run, but you've got to set it large enough for the uncompressed initrd.img and dynamic files that will be created.
[edit] Copying the important files
Something you need to do to get it working..
cp /tmp/vmlinuz-tinygentoo /tmp/initramfs-tinygentoo.igz /mnt/dongle/ umount /mnt/dongle
[edit] BIOS Setup, Reboot and Enjoy!
Reboot, hit Del, F2 or whatever it is that you need to do to enter the BIOS configuration. Find the section where you can change the boot order, and select USB-HDD, USB-ZIP or something similar to have the highest priority. Save and exit, and reboot with the USB stick attached.
[edit] Where to from here?
If all goes well, you'll be in your shiny new TinyGentoo, that you will still need to learn to use though.. You will propably want to write a script to get the net going and maybe something to save your settings.
[edit] TODO
- udev and hotplug
- xorg + wm and stuff
- Getting sectors and cylinders right on the disk
- Scripts and hopefully an ebuild to make life easier
- Boot floppy to get boot the actual TinyGentoo for those whose BIOS's don't support booting directly from USB
[edit] See Also
- man initrd - If you're interested in how the initrd image and stuff works
- http://flashlinux.org.uk - 256mb minumum USB flash disk, but it does look very sweet, and its based on Gentoo.
- http://www.gentoo.org/proj/en/base/embedded/gnap.xml - Gentoo Network APpliance - easy, extremely effective, modular framework for building small, embedded systems (~15MB+).
- http://www.damnsmalllinux.org - 50mb and has X and stuff too.
- HOWTO Small Footprint Gentoo on USB - Great for those who don't want to go with uClibc/have a large flashdisk
- Embedded Gentoo - What all this is based on and wouldn't work without, thank you devs :)
- http://www.bulah.com/embeddedgentoo.html - Something similar to this page, but aimed for embedded instead of desktop
- http://dev.gentoo.org/~iggy/uclibc/gentoo-uclibc-HOWTO - Same stuff as above, just done slightly differently
- http://leaf.sourceforge.net/doc/guide/buci-tz.html - To get the timezone set in uClibc based installs
- http://www.damnsmalllinux.org/talk/node/86 - HOWTO get your USB flash cylinders/tracks/sectors set up so the BIOS won't choke on it
- http://www.gentoo.org/doc/en/liveusb.xml - Official Gentoo LiveUSB howto, using the minimal-livecd.iso
- http://www.kotek.net/minimax - Small (32 MB) livecd based on this on uclibc and gentoo
- http://www.gentoo.org/proj/en/base/embedded/cross-development.xml - Gentoo Cross Development Guide
- HOWTO_Initramfs An interesting page about initramfs in general, and Genkernel's initramfs in particular
- http://jootamam.net/tg-install.htm - Install HOWTO for floppy, CD and USB
