1

I am working on an embedded Linux system (5.10.24), and now I want to check what is the minimal kernel I can build, so with lots of playing of kernel configurations, now I have following kernel.

# dmesg | grep 'Memory:' Memory: 12620K/16384K available (1933K kernel code, 128K rwdata, 236K rodata, 192K init, 55K bss, 3764K reserved, 0K cma-reserved) # free total used free shared buff/cache available Mem: 12812 2624 8808 0 1380 8928 Swap: 0 0 0 

I have disabled some critical kernel codes like sysfs and drivers.
So currently, I cannot optimization in kernel configuration to decrease the kernel memory usage.

This is normal kernel and running on MPU with MMU, for now I may not turn to uCLinux.

Next, I may change the code manually, by disabling or simplifying the kernel codes. But before I do that, I firstly want to narrow down the kernel features which are using more memory than others.

So is there any advice which codes should I focus on firstly? And is there any tool to help me figure out which part of kernel takes more memory which I should pay attention to?

1
  • Consult with OpenWRT. Commented Nov 25, 2023 at 13:09

2 Answers 2

1

I figured out my way to generate a minimal Linux kernel.
Here it is.

  1. Follow the normal and common way to run make menuconfig to go through tons of configurations and disable what is NOT used/needed, this is the risk-less way. Remember to build and boot the kernel to check if the change is working as expected.

  2. Disable kernel components which take memory alot, such as sysfs, procfs and printk. This change will decrease the kernel footprint alot, but which may stop some feature from working, such as free, ps, mount which are heavily relying on procfs. So this is the tradeoff of memory size and functions.

  3. Customize kernel parameters from bootloader, to disable or set some kernel features to use less memory.

  4. with readelf to check which functions and data are taking memory. changing the kernel codes, to simplify some functions based on specific hardware platform, such as the number of IRQs, etc.

It is necessary to build and test the kernel image after each change.

With trials and tests, finally I get the kernel image as follows,

-rw-rw-r-- 1 t t 972961 Nov 29 22:09 vmlinuz text data bss dec hex 1860928 242232 28032 2131192 2084f8 # free total used free shared buff/cache available Mem: 5620 2140 2188 0 1292 2660 Swap: 0 0 0 

With sh disabled

According to paladin's comment, I tried to disable 'sh' in kernel and compared the result.

Before change.

text data bss dec hex 7905846 1791740 135872 9833458 960bf2 

After change

text data bss dec hex 7905026 1787608 135872 9828506 95f89a 

So there are about 800Bytes saved in text and about 3KB in data.

7
  • You can remove most of the kernel debug console output, but it makes error debugging a mess. You can remove the kernel modules option, but you need to include all needed modules into kernel. You can remove support for shell-script-executables (*.sh) from kernel, but when doing so, you need to replace ALL shell-scripts with compiled programs which run before userspace is loaded until your system finally runs in userspace (I really don't recommend this, but it'll save a lot of memory.). Commented Nov 30, 2023 at 9:34
  • PS this also means your init system must be a compiled executable, C example: #include <stdlib.h>; int main(){system("/bin/sh /etc/init.sh"); return 0;} Commented Nov 30, 2023 at 9:41
  • I did try the init with my compiled executable, which open /proc/meminfo and out put the memory info to the /dev/ttyS0. So I did not totally remove the procfs and tty driver, both of them take lot of memory. I can try your advice of "remove support for shell-script from kernel' to get a smaller kernel. In fact, removing printk did save lot of memory, but as you said it cause debugging more diffcult. So it should be kept during development and be disabled in production. Commented Nov 30, 2023 at 12:30
  • PS you also could use very old kernels, if your embedded device doesn't need network conectivity but just a UART, it's possible to reduce kernel size to less than 1 MiB > superuser.com/questions/130457/what-linux-fits-on-a-floppy-disk Commented Nov 30, 2023 at 14:28
  • Yep, I cannot agree more with you! I had this idea but finally I gave it up. Because this kernel is from a SOC vendor, who has added UART driver, LCD driver based on its SOC architecture, changing the kernel is impossible without their support. I bookmarked the link you recommended, and will use it once possible. Commented Dec 1, 2023 at 0:27
0

Its too bad that there is no online kconfig analyzer.

I'm doing a similar thing for pc, not embedded, and I am finding that I can make a tinyconfig for linux-4.2 at ~1000k; but then I have to add features like; tiny+ipc, tiny+acpi, just to suspend the machine or run a shell script (some things are too useful).

I can just about get X to build, so, in a way, I want to add features needed by libc, X, and SSL while still building a small x64 kernel.

I have to recompile the entire dist when the kernel headers change.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.