Instant Buildroot [Instant] — Save 50%
Automate the building process of your embedded system and ease the cross-compilation process with Buildroot with this book and ebook
In this article by Daniel Manchón Vizuete, author of Instant Buildroot, we will learn how to customize a Linux kernel using Buildroot. This article is a must-read for users new to embedded software design, but who already have some experience with software development and Linux.
The Linux kernel is a huge project, and it's full of configuration options and device drivers. Usually, we need to tune the kernel in order to add some basic functionality, integrate the drivers of our devices, or reduce the total size disabling the unused functions and drivers. In this article, we will walk through the most common kernel configuration options.
(For more resources related to this topic, see here.)
How to do it...
- First, we must go to the Buildroot folder (cd $HOME/work/Buildroot).
- We need to modify the kernel options, so enter make linux-menuconfig.
- Enter the General setup menu; we want to enable the LZMA support for the compressed kernel in order to reduce the total size of the system. This compression scheme is far better than standard GZIP, but at the cost of speed, it takes much more time to expand the kernel when booting.
- In order to enable this function, set the Kernel compression mode to LZMA, check the Support initial ramdisks compressed using LZMA option, and set the Built-in initramfs compression mode to LZMA.
Another trick to reduce the size is to embed the RFS into the kernel; by doing this we can profit from the LZMA compression. Also, for the RFS, set the location of the roofs.cpio file in the Initramfs source file(s) option.
- Finally, check the Optimize for size option to enable some compiler flags for allowing the kernel to reduce the final size.
- Inside the Boot menu, we can configure the kernel boot sequence. This option is interesting to add a default command-line argument, which the kernel will use if the bootloader doesn't pass anything. So we can put our kernel arg line here just in case something fails in the bootloader.
- Inside the Networking menu, in the Networking options submenu, there are configurations related to networking protocols. You can configure all of the TCP/IP stack options here. Now, enter the Wireless menu and make sure that cfg80211 is enabled in order to use the Wi-Fi interface later.
- We will now revise the most common modification point in Linux kernel, the Device drivers menu. Here resides all of the options related with the support and configuration of the possible device drivers that Linux supports, so you need to configure here all of the devices that your board has. Also, it's a good idea to disable the support for the drivers that you won't use, so you can reduce the overall size.
- We will add support for Wi-Fi USB devices, so let's enter the Network devices support menu, and then the Wireless LAN submenu. For example, if your USB dongle is a Ralink one, enter Ralink driver support and set your device with an M, which means that you are including support for this device as a module that could be dynamically loaded when the device is detected. The other option will be to mark as an asterisk (*); this will include support inside the kernel itself, so you always have the driver ready. Loadable module drivers are a good idea because it gives you more flexibility and reduces the overall memory occupation when some devices are not needed.
- The next important item is the File systems menu, where the user can select the desired support for filesystems to mount the RFS; in our case, we need to select EXT3/4, NFS, and RAMFS. This is a good place to get more space by getting rid of unused filesystems that our system won't support.
- Now, exit the graphical menu. Linux configuration will be stored in a .config file, which we will save in a secure location in order to retain the changes that we made:
cp output/build/linux-e959a8e/.config $HOME/work/project/linux.config
- We should then teach Buildroot where to get the configuration file for Linux; enter the Buildroot menu using make menuconfig. Go to the Kernel menu and set the Kernel configuration option to using a custom config file, write down the path to the linux.config file, and exit the menu.
- One last change is necessary, because now the RFS resides compressed inside the kernel. We need to modify the U-Boot script in order to not load the RFS, but just the kernel, into memory. Modify the boot script file $HOME/work/project/boot.txt to contain:
load mmc 0:1 $kernel_addr zImage; setenv bootargs "$console_args $ramfs_args" bootz $kernel_addr
- Generate the script file with the command (you can add this line to your post-image.sh in order to generate it automatically each time the system is rebuilt):
../buildroot/output/build/uboot-rpi/tools/mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n 'u-boot script' -d boot.txt boot. scr
- Generate the system with the make command and copy the generated files to the SD card.
- The system should boot into the login prompt; enter the username as root without a password.
How it works...
Kernel configuration is one of the main tasks that any embedded project will face.
The basic steps to configure your system will be to first identify all of the hardware devices on your board, and then the requirements of RFS support and networking protocols.
As advised, usually you can add driver support in two ways: as a loadable module or by directly adding the driver support to the kernel. The module support is good enough to test your system and make the kernel size smaller (because the modules and .ko files reside in the RFS). Anyway, once your system is fully tested and stable, you can add the required drivers into the kernel and remove all of the modules that you don't need in order to reduce the overall size of your system.
Another good idea is to back up your config file with all of the modifications in order to easily go back to working state and share your modifications with the rest of your team.
In this article, we learn about the most important part in any embedded system—the kernel. It has many configurable parameters and support for many external devices. It also helps you learn the basic configurations and how to add support for your peripherals.
Resources for Article :
- Installing VirtualBox on Linux [Article]
- Linux Shell Script: Tips and Tricks [Article]
- Linux Shell Script: Logging Tasks [Article]
About the Author :
Daniel Manchón Vizuete is a Spanish industrial technical engineer. He graduated from UPC university in Barcelona. He specializes in embedded systems programming and design-efficient Linux devices. He has been working for a decade at Sony Europe designing TV software and on different embedded projects, mainly in the automotive, communications, and medical fields. He uses Buildroot as the main tool for setting up efficient and light systems on Linux.