Introduction to buildroot
From buildroot website, buildroot is a set of Makefiles that makes it easy to generate a complete linux system. It can generate cross-compilation toolchain, linux kernel image and bootloader; and even do any other kind of post build steps. It uses the menuconfig(or gconfig or xconfig) interface that is also used to configure linux kernel.
Buildroot contains makefiles contain instructions to fetch sources(from http, git, svn, hg etc) of packages that you select to be present on your root file system, build them using a gcc toolchain that it build to target the target architecture(arm, x86, mips, powerpc).
Download a snapshot of buildroot here. Extract it into some directory and from inside it type ‘make menuconfig’. A kernel menuconfig like interface will come up. The most important thing to configure would be to change the target architecture and target architecture variant configuration. Buildroot can download and build its own toolchain for the target(this internal toolchain is limited to using uClibc C library), but it also provides options to use an external toolchain(which it can download or an installation path can be given), or http://crosstool-ng.org/ toolchains. So if you need to use glibc or eglibc C libary, you need to use an external toolchain(or crosstool-NG).
Buildroot supports three init programs, first is Busybox init, which reads /etc/inittab and follows this syntax. Next is SystemV init, which is very standard and some documentation can be found here. Third option available is systemd, its documentation. For most systems, Busybox should be fine and might also save a very small amount of disk space.
Buildroot has 4 options for /dev management. First is static device table, which uses a static text file which follows this syntax to statically create device files inside /dev. In this method, /dev entries persist during reboots and no addition/deletion occurs on attaching or removing devices. To add your own device table, create a device_table.txt file and set the BR2_ROOTFS_STATIC_DEVICE_TABLE property to the path to this file(you can search property names locations using ‘/’ in menuconfig). Second way is to use ‘Dynamic using devtmpfs only’, which can be used with kernels 2.6.32 and above, and needs CONFIG_DEVTMPFS and CONFIG_DEVTMPFS_MOUNT options enabled in the kernel config to work. This makes /dev/ entries appear and disappear automatically. Third option is ‘Dynamic using mdev’, which also relies on devtmpfs (and so needs CONFIG_DEVTMPFS and CONFIG_DEVTMPFS_MOUNT too). This adds mdev userspace utility which will be called every time a new device is added or removed. Mdev can set device permissions and ownership, or load kernel modules based on device attached event, and can be configures in /etc/mdev.conf(syntax). Last option is using udev, this also needs the devtmps kernel options, and is a daemon which runs in the background and is called by kernel every time a new device is added or removed. This is heavier than mdev, but it can be a requirement in some systems, like those which use systemd.
You can choose to build or not to build kernel along with the rest of the system in buildroot. To access kernel menuconfig, do ‘make linux-menuconfig’. You can always build a kernel outside of buildroot(but be sure to enable kernel options which match your system, like devtmpfs options which are needed for dynamic /dev management).
Buildroot provides a Busybox binary for many system applications, you can access busybox config using busybox-menuconfig. Also, uClibc can also be configured using make uclibc-menuconfig. Also, do not use -j flag with make in buildroot (don’t use make -j 8); instead set BR2_JLEVEL to the required value of parallelism.