How to Lose weight in Linux
Author: nickname Source: network arrangement updated on:
Reduce Linux system usage, reserve more resources for applications, and reduce hardware costs for devices. "How small can you be ?" This problem is usually asked when embedded Engineers start their projects. Most of the time, the people who ask this question want to reduce Ram and flash resources and the unit cost or energy demand of devices.
Because Linux was originally designed for a desktop or server system, by default, it has not been optimized for the size. In any case, Linux is increasingly used in embedded devices, it is not easy to make Linux smaller. Here are several ways to reduce the memory usage of the system.
Many Engineers start from reducing the kernel size. Here is an easy way to start. This article will detail how to reduce the kernel size, it mainly removes the code that is not used in a typical embedded system.
In a system, the root file system (RFS) may be the biggest consumer of memory resources. The root file system includes the infrastructure code used by the application and the C library. Selecting a file system for RFS has a huge impact on the final size. The standard is ext3, which is very inefficient from an embedded engineer's perspective, but that is the topic of another article.
In practice, how can we reduce it?
Even the smallest Linux release has at least two parts: the kernel and the root file system. Sometimes these parts are located in the same file, but they are still divided into different parts. Remove almost all code with similar features from the kernel, so that a system can easily be reduced to less than 1 MB. However, many users choose Linux to support networks and different devices, so this is not a practical practice.
Kernel
The Linux kernel is very interesting. Although it depends on GCC at compilation, it does not depend on it at runtime. Those Engineers turned to Linux to initialize the RAM disk (the so-called initrd), which is an attachment to the kernel runtime. Initrd is first loaded by the kernel. When the program runs, it asks the system what modules need to be loaded to support the device so that the real root file system can be loaded. In fact, there are two loading steps: loading initrd and then loading the real root file system. It is rare to find that there is a root file system in the embedded system, because it will increase flexibility in a system, it takes additional space or time to modify the system. embedded systems generally do not require flexibility. However, this article will discuss the root file system later.
Supported load modules
The kernel loading module relocates the code that the kernel connects to itself during runtime. A typical example of a load-able module is to allow the driver to be loaded into the kernel from the user space (after some probe processes are executed ), and do not disable the system upgrade device driver. For most embedded systems, once they are out of this range, modifying the root file system is either unrealistic or impossible. Therefore, the system designer directly connects the module to the kernel and removes the loaded modules, saving a lot of space for the kernel, program Management can load modules (such as insmod \ rmmod \ lsmod) and shell scripts to load them are not required.
Linux-tiny patch
The Linux-tiny patch set has become a temporary project, initially hosted by Matt macall. The consumer electronic Linux Forum (CLEF) is working hard to restore this project. The clef developer Wiki has released a patch for the 2.6.22.5 kernel (the latest version when writing this article). At the same time, many changes to the Linux-tiny project have been included in the main kernel. Although many original Linux-tiny patches have been integrated into the kernel, the space-saving patches have not yet been integrated.
For example:
1. fine-grain printk support [fine-grained printk support]: users can control what files can use printk. Engineers will not benefit from using the printk file size.
2. Change CRC from calculation to use table lookup [Change CRC algorithm from calculation to use table query]: an Ethernet data packet requires a CRC to verify the accuracy of the data packet. This CRC algorithm replaces the calculation with Table query, saving about 2 K.
3. Network tweaking [network adjustment]: Several patch packages reduce the supported network protocols, cache size, and open sockets. Many embedded devices only support a small number of protocols and do not need services with hundreds of thousands of connections.
4. No panic reporting [no emergency report]: If the device has three status lights and a series of connections, users cannot see them, with less impact, the emergency information is displayed on a non-existent terminal. In case of kernel failure, you only need to restart the device.
5. Reduction of inlining: Direct insertion means that the compiler copies the code as a macro to every position of its call, rather than generating a function call. By default, GCC inserts any function directly. By suppressing the direct insertion of functions, the code runs slowly because the compiler needs to generate code for calls and responses, and the reward is that the object file is smaller.
The Linux-tiny patch is released as a tar package, which can be applied together or separately.
Recommended kernel Adjustment
Although the Linux-tiny project involves many aspects, there are several additional configuration changes to reduce the Linux footprint.
1. Remove ext2/3 support and use another different file system: ext2/3 file system is usually large, larger than 32 K, most engineers enable a flash file system, if ext2/3 is not disabled, the memory will be wasted.
2. Remove the support for sysctl. sysctl allows you to adjust Kernel Parameters during runtime. In most embedded devices, you do not need to change the Kernel configuration once it is set, using this feature wastes 1 K.
3. Reduce IPC options. Most systems do not have sysv IPC features (grep your msget, msgct, msgsnd, and msgrcv code) and POSIX message query (grep MQ _ * [A-Z]). it can run the same way, and it can save 18 K to remove them.
4. view the effects of your changes
The size Command reports the size of all code and data in an object file, which is different from the LS command input. The LS command reports the size of bytes in the file system.
For example, a report on compiling a kernel with armv51 cross compiler is as follows:
# Armv5l-linux-size vmlinx
Text Data BSS dec hex filename
2080300 99904 99312 2279516 22c85c vmlinux
The text section is the code sent by the compiler. The data section includes global and other values that use the initial static symbol. The BSS section includes static data that is adjusted to zero as part of the initialization.
Although this data is enlightening, it does not show the memory consumed by the system, nor can it be obtained by querying vmlinux. However, it is the best thing to create a vmlinux instance by viewing the files connected together, to obtain this information, use the find command to locate the built-in.o file in the kernel project and calculate the size:
# Find.-Name "built-in.o" | xargs armv5l-linux-size
? -- Totals | sort-n-K4
The output of this command is similar to the following:
Text Data BSS dec hex filename
189680 16224 33944 239848 3a8e8./kernel/built-in.o
257872 10056 5636 273564 42c9c./NET/IPv4/built-in.o
369396 9184 34824 413404 64edc./fs/built-in.o
452116 15820 11632 479568./NET/built-in.o
484276 36744 14216 535236 82ac4./Drivers/built-in.o
3110478 180000 159241 3449719 34a377 (totals)
This technology can precisely point out the code that occupies a large amount of space, so engineers can first remove the code. When doing so, the user should execute the compilation clearing action before the creation, because dropping a feature from the kernel does not mean that the previously compiled object file will be deleted.
For things that are newly added to the Linux kernel, a common question is how to use an option in the kernel provisioner to combine some built-in.o files, this can be achieved by viewing the makefile and kconfig files in the directory. The makefile will include a line like the following:
OBJ-$ (config_atalk) + = p8022.o psnap. o
When the configuration variable config_atalk is set, it generates a file on the right hand side. Kernel configuration tools generally do not expose subordinate configuration variable names. To identify the connection between variable names and what is visible, search for variable names without the config _ prefix in kconfig.
Find.-Name kconfig-exec fgrep-H-C3 "Config atalk "{}\;
It will generate the following output:
./Drivers/NET/appletalk/kconfig -#
./Drivers/NET/appletalk/kconfig-# appletalk driver Configuration
./Drivers/NET/appletalk/kconfig -#
./Drivers/NET/appletalk/kconfig: config atalk
./Drivers/NET/appletalk/kconfig-tristate "appletalk protocol support"
./Drivers/NET/appletalk/kconfig-select LLC
./Drivers/NET/appletalk/kconfig---- help ---
Some other things need to be done, because the user needs to find the appletalk protocol support in the configuration tree, but at least need to know what to look
Root file system
For many engineers New to embedded Linux, they think that the root file system on an embedded device is an external concept, the embedded solution before Linux works by directly connecting application code to the kernel, because Linux has a very good separation between the kernel and the root file system, minimizing the system is not the end point of reducing the kernel. before optimization, the size of the root file system is much smaller than that of the kernel. In any case, for traditional Linux, the system part has many parts that need to be adjusted to reduce the size of the system.
The first question to answer is: "Do I need a root file system ?" Simply put, yes. At the end of the kernel startup process, it looks for the root file system and then loads and runs the first process (usually init, executing PS aux | head-2 will tell you what process is on your system). The kernel cannot start without the root file system or any of the initialization programs.
The smallest root file system can be a file: A device application. In this case, the kernel should specify a file, which is the first process in the user space. The system can work as long as the process is running. However, if the program exits for any reason, the kernel will be suspended and the device will need to be restarted. Most systems with limited space will also choose an initialization program, because the internal consumption is small, initialization includes re-generating the dead code of the process, to prevent kernel suspension when the application crashes.
Most Linux systems are complex, including many executable files and common shared libraries (including the application shared library code running on the device). For these file systems, there are many options for reducing the RFS size.
Change C library
In combination with GCC, most users do not want the C library to be an independent entity. The C language includes 32 keywords (give, take, etc.). Therefore, most bytes of the C program come from these standard libraries, the authoritative library C (glibc) is designed to be highly compatible, internationalized, and cross-platform, but it is also relatively large. There are many small libraries available:
Uclibc: This project is a C library for processors without memory management units (MMU-less. Uclibc is very small since its creation. It provides the same functions as the C library, but deletes features such as internationalization, support for large character sets, and binary compatibility. In addition, the uclibc Configuration tool gives users great freedom to choose the code to be imported into the database, allowing users to further reduce the size.
Uclibc ++: for programs that use C ++, this library is implemented under the same design principle and supports most of the functions of the Standard C ++ library, engineers can easily deploy C ++-based applications on the board, requiring only a few megabytes of space.
Newlib: newlib comes from red hat. It has a very complete mathematical library implementation, and many users like it for controlling and measuring applications.
Dietlibc: dietlibc is the best substitute for glibc. It is still the smallest branch, which is very small. In fact, it is only 70 K. It deletes features such as dynamic link library. It supports arm and MIPS well.
Use an alternate C library
Newlib and dietlibc call the compiler to use the correct parameter set by providing a packaged script, ignore the Standard C library included in the compiler, and use a replaced C library. Uclibc is a bit different. It requires tool chain.
Once you know how to call GCC, update the MAKEFILE file or create a script for the project. In most cases, use the following line in the MAKEFILE file for the project:
Cc = CROSS_COMPILE-gcc
In this case, all users need to run the make command from the command line to overwrite the CC variable:
Make cc = dietc
This will cause makefile to call diet for the C compiler. Although it looks attractive, do not add parameters to this macro and use the cflags variable instead. For example:
Make cc = "gcc-OS"
It should be:
Make cc = GCC cflags = "-OS"
This is very important because some rules will call CC compilation, and the parameters will be meaningless and cause errors.
Return to the root file system
After selecting the C library, all the code in the root file system needs to be compiled with a new compiler, so that the code can use the nearest and smaller C library. In this regard, it is worthwhile to evaluate the static and shared libraries. If the device runs any code and the code is unknown during deployment, shared libraries are the best choice. For example, a device may expose an API that allows end users or professional engineers to write modules. In this case, the library on the device should provide the maximum flexibility for these new feature implementations.
If the system includes many separated program shared libraries, it is also the best choice. In this case, the copy of the shared code will be smaller than the same code that copies several files.
When only a few programs are used, the best practice is to create a system for each purpose and compare the final size. In most cases, a smaller system does not share a library, in addition, there is an additional benefit, because the system without a shared library loads and starts the program faster (because there is no connection to this step), so users also benefit from the efficiency perspective.
Summary
Although there is no magic tool to make the system smaller, there is no tool to help make the system only be smaller, and it is more difficult to make Linux smaller than to reduce the kernel size, the root file system needs to be checked strictly because this part consumes more space than the kernel. This article mainly describes the executable image size and reduces the memory requirements of running programs.
Resources
1. Linux-tiny patch: Kernel.
2. gnu c Library: www.gnu.org/software/libc. gnu c standard library is a standard implementation of C library, which can be run on almost all platforms and is backward compatible.
3. uclibc: www.uclibc.org. A smaller C library.
4. newlib: small C library of sourceware.org/newlib. Red Hat.
5. dietlibc: www.fefe.de/dietlibc. Minimum C library