Embedded Linux init Explained: BusyBox, SysVinit, and systemd
Every Linux system begins with a special process: PID 1. Regardless of whether the platform is a tiny IoT device, an industrial controller, or a cloud server, the initialization processβcommonly referred to as initβis responsible for bringing the entire operating system to life.
For embedded Linux developers, understanding how init works is essential. It directly affects system startup behavior, service management, boot time optimization, and overall system reliability.
This article provides an in-depth look at the Linux init process, compares the three major initialization systems used in embedded Linux, and explains how application autostart mechanisms differ among them.
π What Is the init Process? #
The init process is the first user-space process started by the Linux kernel.
Its Process ID is always:
PID = 1
Once the kernel finishes hardware initialization and mounts the root filesystem, it launches the init process. From that point forward, init becomes the parent of all user-space processes, either directly or indirectly.
A simplified boot sequence looks like this:
Bootloader
β
Linux Kernel
β
Mount Root Filesystem
β
Start init (PID 1)
β
Initialize Services
β
Launch User Applications
Core Responsibilities of init #
The init process is responsible for:
- Initializing system services
- Launching background daemons
- Starting login consoles
- Managing service lifecycles
- Handling system shutdown and reboot procedures
- Re-parenting orphaned processes
- Monitoring critical services
Because every application ultimately depends on PID 1, selecting the appropriate init system is an important architectural decision for embedded Linux platforms.
π§ Types of init Systems #
Modern embedded Linux systems generally use one of three initialization frameworks:
- BusyBox init
- SysVinit
- systemd
Most embedded Linux build systems, including Buildroot and Yocto, support one or more of these options.
Identify the Current init System #
To determine which init system a running Linux device uses:
cat /proc/1/comm
Example outputs:
init
systemd
busybox
β‘ BusyBox init: The Lightweight Choice #
BusyBox init is designed specifically for resource-constrained embedded systems.
It is:
- Extremely small
- Fast to boot
- Easy to configure
- Well suited for flash-based devices
Buildroot uses BusyBox init as its default initialization system because it minimizes memory and storage requirements.
Advantages #
- Minimal footprint
- Very low memory consumption
- Fast startup time
- Simple configuration
Limitations #
- Limited dependency management
- No advanced service supervision
- Less flexible than systemd
For many embedded products such as routers, industrial controllers, and IoT devices, BusyBox init provides everything necessary without unnecessary complexity.
ποΈ SysVinit: The Traditional Approach #
SysVinit originated from AT&T’s System V UNIX and became the dominant Linux initialization framework for decades.
Before the rise of systemd, nearly every major Linux distribution relied on SysVinit.
Key Characteristics #
- Script-driven startup
- Runlevel-based management
- Sequential service execution
- Mature and predictable behavior
Although newer alternatives exist, SysVinit remains popular in many embedded environments due to its simplicity and transparency.
π systemd: The Modern Service Manager #
systemd is currently the dominant initialization system across desktop, server, and enterprise Linux distributions.
Major distributions such as Ubuntu, Fedora, Debian, and Red Hat Enterprise Linux have fully adopted systemd.
Unlike BusyBox init and SysVinit, systemd provides a comprehensive platform for:
- Service management
- Dependency tracking
- Logging
- Device management
- User sessions
- Network configuration
Key Benefits #
- Parallel service startup
- Dependency-aware scheduling
- Integrated logging
- Automatic service recovery
- Advanced monitoring capabilities
These features significantly reduce boot times and simplify large-scale system administration.
π How Autostart Works in Different init Systems #
One of the most important responsibilities of an init system is launching applications automatically during system startup.
Each init framework handles this differently.
π SysVinit Autostart Mechanism #
SysVinit relies heavily on startup scripts.
The primary configuration file is:
/etc/inittab
After boot, init reads this file and executes startup scripts such as:
/etc/init.d/rcS
/etc/init.d/rcK
Typically:
rcShandles system startuprcKhandles shutdown operations
Startup Script Naming Convention #
SysVinit scripts usually follow the format:
Sxxname
Where:
S= Startxx= Execution order
Examples:
S10network
S20syslog
S50sshd
S99application
Lower numbers execute first.
A typical startup script iterates through these entries and executes them sequentially.
Advantages #
- Easy to understand
- Transparent execution flow
- Simple debugging
Drawbacks #
- Serial startup execution
- Poor scalability
- Longer boot times as services increase
As modern systems grow more complex, the limitations of sequential startup become increasingly apparent.
βοΈ BusyBox init Autostart Mechanism #
BusyBox init follows a similar philosophy to SysVinit but removes much of the complexity.
In many ways, BusyBox init can be viewed as a streamlined subset of SysVinit.
Configuration Files #
BusyBox init primarily uses:
/etc/inittab
and
/etc/init.d/rcS
Common Startup Methods #
Method 1: rcS Startup Scripts #
Add commands directly into:
/etc/init.d/rcS
This is ideal for:
- One-time initialization
- Hardware setup
- Simple startup tasks
Method 2: inittab Entries #
Applications can also be managed through:
/etc/inittab
Example:
myapp::respawn:/usr/bin/myapp
The respawn action automatically restarts the application if it exits unexpectedly.
This mechanism provides a lightweight way to keep critical services running without requiring a dedicated service manager.
π systemd Autostart Mechanism #
systemd replaces traditional startup scripts with Unit Files.
Instead of writing shell scripts, developers create service descriptions that define:
- Executable paths
- Startup order
- Dependencies
- Restart policies
- Logging behavior
systemd automatically analyzes dependencies and launches services in parallel whenever possible.
Custom service definitions are typically stored in:
/etc/systemd/system/
Creating a Custom systemd Service #
Step 1: Install the Application #
Copy the executable to a standard location:
sudo cp ~/hello /usr/local/bin/
Make it executable:
sudo chmod +x /usr/local/bin/hello
Step 2: Create a Service Unit #
Create:
/etc/systemd/system/hello.service
Example:
[Unit]
Description=Hello Systemd Demo Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/hello
Restart=always
RestartSec=5s
User=nobody
Group=nogroup
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Important Parameters #
| Parameter | Description |
|---|---|
Type=simple |
Service process starts directly |
ExecStart |
Path to executable |
Restart=always |
Automatically restart on exit |
RestartSec=5s |
Wait 5 seconds before restart |
User |
Run as specified user |
StandardOutput=journal |
Send logs to systemd journal |
WantedBy=multi-user.target |
Enable startup in multi-user mode |
Step 3: Activate the Service #
Reload systemd:
sudo systemctl daemon-reload
Start the service:
sudo systemctl start hello.service
Verify status:
sudo systemctl status hello.service
Enable automatic startup:
sudo systemctl enable hello.service
systemd creates symbolic links within:
/etc/systemd/system/multi-user.target.wants/
The service will now start automatically on every boot.
π Verifying Autostart Configuration #
After configuring a service, reboot the system:
sudo reboot
Verify the service status:
systemctl status hello.service
Common systemd Commands #
| Command | Purpose |
|---|---|
sudo systemctl start hello |
Start service |
sudo systemctl stop hello |
Stop service |
sudo systemctl restart hello |
Restart service |
sudo systemctl enable hello |
Enable autostart |
sudo systemctl disable hello |
Disable autostart |
systemctl status hello |
Show service status |
journalctl -u hello -b |
Show boot logs |
journalctl -u hello -f |
Follow logs in real time |
π Comparing init Systems #
The three major initialization systems target different deployment requirements.
| Feature | BusyBox init | SysVinit | systemd |
|---|---|---|---|
| Footprint | Very Small | Small | Large |
| Boot Speed | Fast | Moderate | Fast |
| Service Dependencies | No | Limited | Advanced |
| Parallel Startup | No | No | Yes |
| Service Monitoring | Basic | Basic | Advanced |
| Resource Usage | Lowest | Low | Higher |
| Embedded Suitability | Excellent | Good | Depends on Resources |
π― Choosing the Right init System #
The best choice depends on your project’s requirements.
BusyBox init #
Recommended for:
- Resource-constrained devices
- Microcontrollers running Linux
- Routers
- Consumer IoT products
- Simple industrial systems
SysVinit #
Recommended for:
- Legacy embedded platforms
- Existing maintenance projects
- Systems requiring predictable script-based startup
systemd #
Recommended for:
- High-end embedded Linux devices
- Industrial gateways
- Edge AI platforms
- Network appliances
- Embedded servers
Buildroot and Yocto Considerations #
Buildroot defaults to BusyBox init because of its lightweight design.
Yocto historically used SysVinit by default but now provides mature support for systemd, making migration straightforward for projects that require advanced service management.
π Summary #
Although the init process occupies only a single PIDβPID 1βit serves as the foundation of the entire Linux user-space environment.
From the minimalistic design of BusyBox init, through the proven stability of SysVinit, to the feature-rich architecture of systemd, each solution addresses different requirements and deployment scenarios.
For embedded Linux developers, understanding how each init system worksβand how applications are automatically started during bootβis essential for building reliable, maintainable, and efficient products.
Selecting the right initialization framework early in a project can simplify deployment, reduce maintenance costs, improve boot performance, and ensure long-term system stability.