In my previous article (Monitor linux) I wrote, what is this distro and how it works. Now i will write how to do it. It's may be interesting for everyone, who want to study buildroot. The result we get from article is the following: There are many different ways to build custom linux-based firmware: In my work way I have used all this ways in different projects. But buildroot is the best way for cross-platform firmware development. It's a simple and powerful system, based on Makefile's. You can customize everything, but is fully functional out of the box.
I mean, that you don't need a lot of time to do something. There are many ready configs for a lot of SBC. Of course, you can customize them: from hostname change to giant high-customizable project. Now, why i use external tree? Of course, it's possible to store all you changes (board and kernel configs, packages, files, etc) in buildroot main directory. But it's not comfortable. External tree is more progressive way.
Strongly recommend to read previous article to undestand external-tree work. My philosophy: only board-specific files (like board/kernel config file, bootloader files and genimage config) are stored in board separate directory. But some data must be ALWAYS identical for all boards: Ok, let's look onto external-tree directory: external.desc, external.mk, Config.in — this files define external-tree and it's packages. Board,configs — it's directores with board-specific files.
All other dirs and files IDENTICAL for all target boards.
buildroot_patches — patches applied to buildroot
package — directory with my packages(zabbix and rodos5_6 for thermometer) post-build.sh — run scripts from post-build directory on post-build stage. Of course, i can point all this scripts directory in board defconfig, but it's not jedi way. More comfortable is to point one script in board config. This script run scripts from post-build dir in alphanumeric order. rootfs_overlay — Buildroot can overlay your directory below target filesystem. It's good way to put custom files in firmware. systemd — It's storage with my custom systemd unit files and them scripts. Yes, i can store them in rootfs_overlay, but I am a couch potato. I wrote post-build scripts, that do this work for me (post-build/0010-system-customization.sh): post-image
By analogy of post-build scripts, this scripts run AFTER building system image is complete. I use them to create usb-flash image and update arch. utils — directory with self-written scripts, doesn't used in firmware build. Now only one script — autobuild. genDataImage.cfg — config file for genimage util. Generate data-partition, identical for all boards. Ok, let's look onto rootfs overlay. I am using it to save static scripts like standalone scripts, logrotate configs(pgp-fpm and lighttpd need it), web-interface files. Now, a love to store bash-scritps functions in one big file that i use as library in my scripts. It's usr/lib/monitor_lib.sh file. Next, comfortable to use global variables in my scripts. I want to use $SETTINGS variable in all my scripts for settings-file path. Best way — use profile. Look to rootfs_overlay/etc/profile.d/monitorVariables.sh: Ok, next task — default config of system. I live to do firmware: unchangeable kernel+initramfs and changeable text file with settings. I save this file inside system image — it's a guarantee that i will always have correct default config. Next question — how to apply changes to all platform. If you use my overlay struct, this task is simple. I am using MELD for this. But you can use any file comparsion tool:  It's one of the powerful buildroot opportunities for me.  On this stage, you can do EVERETHYNG with targer root filesystem, change any files!
You can see that i use it for everything: I have to use 2-staged system restore system
Why i do it? Because i don't radical rewrite unit dependencies.
In first script i prepare system (mount,hostname,network,passwors,etc).
In second i prepare zabbix (files,databases). Before i can do it, i should start postgresql.  Postgresql need network, and etc dependencies.
IMPORT SQL DUMP -> need running postgresql
postgresql -> need ready network
network -> need config file
network config -> must be restored from system settings file. How it work:
system start -> some targets -> multi-user.target
multi-user.target -> settings_restore.service -> network.service,postgresql.service, systemd-networkd.service systemd-resolved.service -> prepare.service -> system start You can see, that possible to run scripts in strong order in systemd. But it's dont mean that i love systemd :-D So, you can see how buildroot can create cross platform firmware without hard work. Important moments: