Poky-Tiny
Poky-tiny is a variant of the poky distribution which is stripped down to minimal configuration.
Introduction
It is intended to be useful for a few different purposes:
- as a demonstration of techniques useful for reducing other images
- as a springboard for very low-end distributions and images
- as a place to experiment with whole-system optimization techniques
It was written by Darren Hart.
Basic use
To use the poky-tiny distro, adjust the DISTRO setting in your conf/local.conf file. That is, set it to: "DISTRO=poky-tiny"
poky-tiny does not include a target-side package manager, so it is useful, to avoid extra dependencies, to use it with the IPKG package management scheme. This is the lightest-weight package management scheme. Set this in your conf/local.conf file:
PACKAGE_CLASSES ?= "package_ipk"
Then do a basic build of the system:
$ bitbake core-image-minimal
Resulting images should appear in your <build-dir>/tmp/deploy/images directory.
FAQ
- where is poky-tiny defined?
- poky-tiny is defined in <yocto-dir>/meta-yocto/conf/distro/poky-tiny.conf. Some other recipes and images have been modified to support the features in poky-tiny.
- The kernel recipe for poky-tiny is in <yocto-dir>/meta/recipes-kernel/linux/linux-yocto-tiny_x.x.bb
- What images are supported?
- As of poky-danny-8.0 (the 1.3 release of yocto), poky-tiny.conf defined the following images: IMAGE_FSTYPES = "ext2 cpio.gz" This means it will build both an ext2 filesystem image, and a cpio.gz image (suitable for use as an initramfs).
- What machines are supported (are there any restrictions)?
- in the kernel recipe file, it has COMPATIBLE_MACHINE="(qemux86)"
- What features have been eliminated?
- What is the size difference between poky-tiny and poky (core-image-minimal)?
- Are there differences in the way poky-tiny is customized, from the way default 'poky' is customized? (eg. gotchas for adding to IMAGE_INSTALL or IMAGE_FEATURES)?
Creating your own tiny-based distro
You can create your own distro, based on the tiny work, by copying the poky-tiny.conf file to your own layer, and editing it from there.
Assuming you are calling your layer 'meta-foo', you could do the following:
- create your meta-foo layer (see other docs for this)
- copy the poky-tiny distro configuration file to your own layer
$ install -p meta-foo/conf/distro $ cp meta-yocto/conf/distro/poky-tiny.conf meta-foo/conf/distro/foo-tiny.conf
- edit your conf/local.conf to use your foo-tiny.conf distro
$ vi <build-dir>/conf/local.conf [change it so "DISTRO?=foo-tiny"]
Adjusting poky-tiny
Controlling LIBC features
Inside foo-tiny.conf (derived from poky-tiny.conf), you can specify what LIBC features to support by modifying the DISTRO_FEATURES_LIBC variable.
This variable is declared to be a space-separated list of other DISTRO_FEATURES_LIBC_xxx variables. To turn on or off features in libc, edit the values of these variables.
eglibc
To see different options that are available, see the file: <yocto-dir>/meta/recipes-core/eglibc/eglibc-options.inc
Listed in that file are the routines: distro_features_check_deps() and features_to_eglibc_settings(), which map items listed in DISTRO_FEATURES_LIBC into specific eglibc settings.
uclibc
To see different options that are available, see the file: <yocto-dir>/meta/recipes-core/uclibc/uclibc-config.inc
Listed in that file is the routine: features_to_uclibc_settings(), which maps items listed in DISTRO_FEATURES_LIBC into specific uclibc settings.
Controlling kernel features
Controlling busybox features
To adjust busybox features, it's necessary to have your own defconfig. Then the busybox recipe must be appended (or you need your own busybox recipe) to tell bitbake where it can find this defconfig. An example:
$ cd /path/to/poky/directory/meta-new-layer $ tree recipes-core/ recipes-core/ ├── busybox_1.20.2 │ └── defconfig └── busybox_1.20.2.bbappend 1 directory, 2 files $ cat recipes-core/busybox_1.20.2.bbappend FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" PACKAGES =+ "${PN}-mdev" $ diff recipes-core/busybox_1.20.2/defconfig ../meta/recipes-core/busybox/busybox-1.20.2/defconfig 530d529 < CONFIG_MDEV=y 536d534 < CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y
In this example you can see how in a new layer, the busybox_<version>.bbappend file modifies the FILESEXTRAPATHS, which enables bitbake to find the corresponding defconfig in meta-new-layer/recipes-core/busybox_1.20.2. In the example defconfig, mdev gets enabled by setting the variables CONFIG_MDEV and CONFIG_FEATURE_MDEV_LOAD_FIRMWARE. The original defconfig that would be used by poky normally is stored in meta/recipes-core/busybox/busybox-<version>/defconfig as of this writing. PACKAGES += just makes sure that busybox-mdev gets packaged because it doesn't do this by default.
In general: Set the FILESEXTRAPATHS so bitbake finds your defconfig and put whatever you like into your defconfig.
Troubleshooting the build
Invoking qemu with poky-tiny images
runqemu can be used to run a poky-tiny image. For instance, for a poky-tiny qemux86 build, try:
$ runqemu qemux86 ramfs
If that doesn't work, try executing qemu directly instead. Here's the template:
$ qemu-system-i386 -kernel path/to/kernel -initrd path/to/image.cpio.gz -nographic -append "console=ttyS0 root=/dev/ram0"
Here the actual full command I used:
$ tmp/sysroots/x86_64-linux/usr/bin/qemu-system-i386 -kernel tmp/deploy/images/qemux86/bzImage-qemux86.bin -initrd tmp/deploy/images/qemux86/core-image-minimal-qemux86.cpio.gz -nographic -append "console=ttyS0 root=/dev/ram0"
Some information about the running system
You can poke around, and see the status of various things. 'ps' shows only 22 processes running, with only 3 user-space (ie not kernel threads):
# ps | grep -v [[] PID USER VSZ STAT COMMAND 1 root 2004 S {init} /bin/sh /init 38 root 2144 S sh 41 root 2144 R ps
So... busybox is really the only executable on the system, and it is providing /bin/sh. /init is a shell script, which will run /etc/rc.local, if one is present. There's a sample in /etc/rc.local.sample that you can use as a starting point to customize the init process. If you turn on packages in yocto, there will be init scripts deposited in /etc/init.d, which you can call from either /init or /etc/rc.local to invoke (none of that fancy sysV rc init scripts here!)
I booted with mem=24M (that was about as small as I could go) and saw the following memory utilization:
# free total used free shared buffers Mem: 19724 5944 13780 0 0 -/+ buffers: 5944 13780 Swap: 0 0 0
The filesystem is a little over 3M in size:
# du -sh / 3.2M /
Here's a sample of what the filesystem looks like (as of yocto-danny-8.0), with results sorted by size and /sys, /proc and /dev omitted:
# find / -type f -xdev | xargs ls -laSr -rw-r--r-- 1 root root 0 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.dep -rw-r--r-- 1 root root 0 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.builtin.bin -rw-r--r-- 1 root root 0 Nov 14 00:45 /etc/network/nm-disabled-eth0 -rw-r--r-- 1 root root 0 Nov 14 00:45 /etc/motd -rw-r--r-- 1 root root 0 Nov 14 00:14 /etc/ld.so.conf -rw-r--r-- 1 root root 0 Nov 14 00:45 /etc/default/usbd -rw-r--r-- 1 root root 6 Nov 14 22:05 /var/volatile/run/ifstate -rw-r--r-- 1 root root 8 Nov 14 00:45 /etc/hostname -rw-r--r-- 1 root root 12 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.symbols.bin -rw-r--r-- 1 root root 12 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.dep.bin -rw-r--r-- 1 root root 12 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.alias.bin -rw-r--r-- 1 root root 13 Nov 14 21:24 /etc/version -rw-r--r-- 1 root root 13 Nov 14 21:24 /etc/timestamp -rw-r--r-- 1 root root 26 Nov 14 00:45 /etc/host.conf -rw-r--r-- 1 root root 38 Nov 14 00:45 /etc/filesystems -rw-r--r-- 1 root root 44 Nov 14 00:45 /etc/hosts -rw-r--r-- 1 root root 45 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.alias -rwxr-xr-x 1 root root 49 Nov 14 00:22 /usr/share/udhcpc/default.script -rw-r--r-- 1 root root 49 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.symbols -rw-r--r-- 1 root root 52 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.devname -rw-r--r-- 1 root root 72 Nov 14 00:45 /etc/issue.net -rw-r--r-- 1 root root 74 Nov 14 00:45 /etc/issue -rwxr-xr-x 1 root root 93 Nov 13 20:19 /etc/default/devpts -rw-r--r-- 1 root root 109 Nov 14 00:45 /etc/shells -rw-r--r-- 1 root root 131 Nov 14 21:24 /lib/modules/3.4.11-yocto-tiny/modules.softdep -rw-r--r-- 1 root root 132 Nov 14 00:45 /etc/network/interfaces -rwxr-xr-x 1 root root 152 Nov 14 00:45 /etc/skel/.profile -rwxr-xr-x 1 root root 270 Nov 13 20:19 /etc/init.d/hostname.sh -rwxr-xr-x 1 root root 289 Nov 13 20:19 /etc/init.d/reboot -rwxr-xr-x 1 root root 321 Nov 13 20:19 /etc/init.d/save-rtc.sh -rwxr-xr-x 1 root root 410 Nov 14 00:45 /etc/skel/.bashrc -rwxr-xr-x 1 root root 438 Nov 13 20:19 /etc/init.d/sendsigs -rw-r--r-- 1 root root 446 Nov 14 21:23 /etc/group -rw-r--r-- 1 root root 465 Nov 14 00:45 /etc/nsswitch.conf -rwxr-xr-x 1 root root 473 Nov 14 21:24 /init -rwxr-xr-x 1 root root 492 Nov 13 20:19 /etc/init.d/banner.sh -rwxr-xr-x 1 root root 510 Nov 13 20:19 /etc/init.d/halt -rwxr-xr-x 1 root root 516 Nov 13 20:19 /etc/init.d/umountfs -rwxr-xr-x 1 root root 526 Nov 13 20:19 /etc/init.d/devpts.sh -rwxr-xr-x 1 root root 578 Nov 13 20:19 /etc/init.d/single -rwxr-xr-x 1 root root 585 Nov 13 20:19 /etc/init.d/rmnologin.sh -rw-r--r-- 1 root root 586 Nov 14 00:20 /usr/share/run-postinsts/run-postinsts.awk -rwxr-xr-x 1 root root 609 Nov 14 00:20 /etc/init.d/run-postinsts -rwxr-xr-x 1 root root 632 Nov 14 00:45 /etc/rc.local.sample -rw-r--r-- 1 root root 651 Nov 14 00:22 /etc/syslog-startup.conf.busybox -rwxr-xr-x 1 root root 660 Nov 13 20:19 /etc/init.d/sysfs.sh -rw-r--r-- 1 root root 704 Nov 14 00:45 /etc/fstab -rwxr-xr-x 1 root root 711 Nov 13 20:19 /etc/init.d/umountnfs.sh -rw-r--r-- 1 root root 719 Nov 14 21:23 /etc/passwd -rw------- 1 root root 737 Nov 14 22:22 /.ash_history -rw-r--r-- 1 root root 783 Nov 14 21:24 /etc/ld.so.cache -rwxr-xr-x 1 root root 809 Nov 14 00:45 /etc/network/if-pre-up.d/nfsroot -rw------- 1 root root 836 Nov 14 21:24 /var/volatile/cache/ldconfig/aux-cache -rw-r--r-- 1 root root 847 Nov 14 00:45 /etc/profile -rwxr-xr-x 1 root root 859 Nov 13 20:19 /etc/init.d/mountall.sh -rwxr-xr-x 1 root root 878 Nov 14 00:45 /etc/init.d/modutils.sh -rw-r--r-- 1 root root 887 Nov 14 00:45 /etc/rpc -rw-r--r-- 1 root root 1123 Nov 13 20:19 /etc/init.d/functions.initscripts -rwxr-xr-x 1 root root 1349 Nov 13 20:19 /etc/init.d/urandom -rwxr-xr-x 1 root root 1540 Nov 13 20:19 /etc/init.d/mountnfs.sh -rw-r--r-- 1 root root 1633 Nov 14 00:45 /etc/inputrc -rwxr-xr-x 1 root root 1711 Nov 14 00:22 /etc/init.d/syslog.busybox -rw-r--r-- 1 root root 1740 Nov 13 20:19 /etc/default/volatiles/00_core -rwxr-xr-x 1 root root 1752 Nov 13 20:19 /etc/init.d/bootmisc.sh -rwxr-xr-x 1 root root 1909 Nov 14 00:45 /etc/init.d/networking -rw-r--r-- 1 root root 2146 Nov 14 00:22 /etc/busybox.links -rwxr-xr-x 1 root root 2514 Nov 14 00:22 /etc/init.d/hwclock.sh -rwxr-xr-x 1 root root 2548 Nov 14 00:22 /etc/udhcpc.d/50default -rw-r--r-- 1 root root 2933 Nov 14 00:45 /etc/protocols -rwxr-xr-x 1 root root 3229 Nov 13 20:19 /etc/init.d/checkroot.sh -rwxr-xr-x 1 root root 4409 Nov 13 20:16 /usr/sbin/update-rc.d -rwxr-xr-x 1 root root 4524 Nov 14 00:45 /usr/bin/update-alternatives -rwxr-xr-x 1 root root 5249 Nov 13 20:19 /etc/init.d/populate-volatile.sh -rwxr-xr-x 1 root root 6666 Nov 13 20:19 /etc/device_table -rwsr-xr-x 1 root root 9544 Nov 14 00:14 /usr/lib/eglibc/pt_chown -rwxr-xr-x 1 root root 9740 Nov 14 00:14 /lib/libutil-2.16.so -rwxr-xr-x 1 root root 13828 Nov 14 00:14 /lib/libdl-2.16.so -rw-r--r-- 1 root root 19398 Nov 14 00:45 /etc/services -rwxr-xr-x 1 root root 22020 Nov 14 00:14 /lib/libnss_dns-2.16.so -rwxr-xr-x 1 root root 26064 Nov 14 00:14 /lib/libcrypt-2.16.so -rwxr-xr-x 1 root root 30624 Nov 14 00:14 /lib/librt-2.16.so -rwxr-xr-x 1 root root 34588 Nov 14 00:14 /lib/libnss_compat-2.16.so -rwxr-xr-x 1 root root 46980 Nov 14 00:14 /lib/libnss_files-2.16.so -rwxr-xr-x 1 root root 83716 Nov 14 00:14 /lib/libresolv-2.16.so -rwxr-xr-x 1 root root 87860 Nov 14 00:14 /lib/libnsl-2.16.so -rwxr-xr-x 1 root root 96128 Nov 14 00:14 /lib/libpthread-2.16.so -rwxr-xr-x 1 root root 127228 Nov 14 00:14 /lib/ld-2.16.so -rwxr-xr-x 1 root root 251328 Nov 14 00:14 /lib/libm-2.16.so -rwxr-xr-x 1 root root 524924 Nov 14 00:14 /sbin/ldconfig -rwsr-xr-x 1 root root 554820 Nov 14 00:22 /bin/busybox -rwxr-xr-x 1 root root 1056128 Nov 14 00:14 /lib/libc-2.16.so
busybox, ldconfig and libc (and other libc-related libs) make up about 95% of the system.
If busybox were statically linked, and ldconfig and libc were omitted, I believe it would reduce the size of the system substantially.
exiting the system
There is no 'shutdown' command, but you can use 'ctrl-a to execute a command to the qemu monitor, and 'ctrl-a b' to issue a sysrq to the Linux kernel. You can do a sysrq-B to do a reboot. Do: ctrl-a h to see available commands, and ctrl-a x to exit qemu.
Resources
- Presentation: Tuning Linux For Embedded Systems: When Less Is More by Darren Hart, ELC Europe 2011, October 2011, Prague, Czech Republic