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