Create your own OS with buildroot on Snowball

Buildroot

Buildroot is a building environment which builds from scratch a full operating system directly from the sources, setting up a minimal configuration. Is configurable via Kconfig and is possible to build for multible platforms.

The cool thing about buildroot and the reason why I prefer it over the others is that the image built is very small and as you will see it's fairly easy to create.

Another cool property is that all the sources are fetched using git (alas sometimes hg)

Set up the SD Card

On our case we need a micro SD card, the minimum size could be relatvely small, by using buildroot 128MB are more than enough.

The partition table of the micro SD should look like this (in my case the SD memory is sdc):

  • sdc1 32M W95 FAT32
  • sdc2 whatever Linux

The first partition is the one who should hold the Linux Kernel, therefore it's important to create a FAT32 file system. The sizes are not important.
While the second partition contains the whole file system in ext3 or ext4 structure.

Get the sources and compile

Download buildroot directly from the sources

$ git clone git://git.buildroot.net/buildroot
$ cd buildroot

configure it

$ make calao_snowball_defconfig

At this point could be useful to add some more packages to the build. By running

$ make menuconfig

you get into a menu where it is possible to add more software, like ssh, less, vim, etc. If you are familiar with the Linux Kernel, this buildroot's menuconfig reminds the linux menuconfig, also the shortcuts are the same (use '/' to search the package you wish).

Once you saved the configurations just hit

$ make

and it will start compiling everything you selected. The compilation of course will take quite a long time.

After the compilation buildroot stores the needed files in

$ cd output/images

where you can find:

  • rootfs.tar and rootfs.tar.gz: contains the filesystem
  • u-boot.bin: the preconfigured bootloader (this file may be unnecessary if the native uboot loads the kernel properly)
  • uImage: the image of the Kernel

Moreover in output/host/usr there is a complete toolchain used for compiling on the new OS.

In order to configure the target kernel for your needs, run

$ make linux-menuconfig

The target kernel .config file is then saved under output/build/{target_kernel}.

In the buildroot configuration that was mentioned earlier (make menuconfig), make sure to set the path your custom .config file correctly under the Kernel menu and re-run

$ make

Setting up the OS

Plug the memory card on the host computer and mount the two partitions (if not done automatically).

Let's assume

# mount /dev/sdc1 /mnt/sdc1
# mount /dev/sdc2 /mnt/sdc2

Now untar the rootfs.tar.gz into sdc2

# tar -C /mnt/sdc2 -xvfz /<buildroot_path>/output/images/rootfs.tar.gz

and copy the Kernel into sdc1

# cp /<buildroot_path>/output/images/uImage /mnt/sdc1/

umount the memory stick and you are ready to boot.

First boot

Insert the microSD in the snowball device and press the power button. The device should boot from SD as it is, with no need to touch the bootloader.

How to compile and boot the Mainline Kernel

Get the sources directly from git

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux

Make sure the cross-compiling (ARCH and CROSS_COMPILE) environment variables are set, if not set them:

$ export ARCH=arm

There are many places where to get the cross compiler. Debian provides already a cross compiler; if you use debian, just follow these instructions

If you have Debian set the cross compiler as:

$ export CROSS_COMPILE=arm-linux-gnueabi-

You could get them from linaro here or you can take the chance to compile it by your own directly from the source

Otherwise it's possible to use the crosscompiler built with buildroot:

$ export CROSS_COMPILE=arm-buildroot-linux-uclibcgnueabi-

Now we are ready to compile. Configure the Kernel:

$ make u8500_defconfig

and compile the uImage with load address 00008000. The uImage is the Linux Kernel image compatible with the u-boot bootloader.

$ make uImage LOADADDR=00008000

Compile the modules

$ make modules

Now it's time to enable and install the just compiled Kernel. Insert the SD card in your computer and mount it

$ mount /dev/sdc1 /mnt/sdc1
$ mount /dev/sdc2 /mnt/sdc2

Install the Kernel

$ cp <path_to_linux>/arch/arm/boot/uImage /mnt/sdc1

Install the modules

$ cd <path_to_linux>
$ INSTALL_MOD_PATH=/dev/sdc2 make modules_install

Umount the sd card, insert it to the snowball, boot and enjoy!

If happens that you get these kind of error during boot:

can't open /dev/null: No such file or directory
...
can't open /dev/ttyAMA2: No such file or directory

it's because at this stage of the /dev directory is not populated yet. You can ask to the kernel to create a tmpfs fully functional with udev already at the early stage of the device boot up. To do set:

CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y

If you are not familiar with the above variables, enter the menuconfig of your Kernel:

$ make menuconfig

and browse through the menu and make sure you set the following

Device Drivers  --->
    Generic Driver Options  --->
        [*] Maintain a devtmpfs filesystem to mount at /dev
        [*]   Automount devtmpfs at /dev, after the kernel mounted the rootfs

What if the bootloader doesn't boot from SD?

How to log with minicom


for questions, corrections, doubts, feel free to contact Andi Shyti andi@etezian.org