This project implements a custom embedded Linux system image with a daemonized TCP socket service, built and validated using Buildroot and QEMU (AArch64).
The goal of the project was not just to write a socket program, but to integrate a network service properly into an embedded Linux environment: cross-compilation, init scripts, signal handling, reproducible builds, and system-level validation.
Host machine
(Ubuntu, sh)
┌───────────────────────────────────────────────┐
│ │
│ netcat / sockettest.sh / full-test.sh │
│ │ │
│ ├── TCP :9000 ─────────────────────┐ │
│ │ │ │
│ └── SSH/SCP :10022 ───────────────┐ │ │
│ │ │ │
└──────────────────────────────────────────┼─┼──┘
│ │
QEMU port fwd │ │
│ │
┌──────────────────────────────▼─▼──────────────────────────────────┐
│ QEMU (AArch64) │
│ Buildroot Linux system image │
│ │
│ init (BusyBox) │
│ └── /etc/init.d/S99aesdsocket │
│ └── start-stop-daemon │
│ └── /usr/bin/aesdsocket -d │
│ │ │
│ ├─ listens on TCP :9000 │
│ ├─ syslog │
│ └─ file state: /var/tmp/aesdsocketdata │
│ │
│ │
│ dropbear (SSH server) listens on :22 │
└───────────────────────────────────────────────────────────────────┘
The system consists of three tightly integrated parts:
- A TCP socket server (
aesdsocket) written in C - Service lifecycle management (daemon mode + init integration)
- A reproducible embedded Linux image built using Buildroot and executed on QEMU
The socket service listens on port 9000, accepts newline-delimited input, appends data to a file on disk, and returns the aggregated contents to the client. The service runs as a daemon, starts automatically at boot, and shuts down cleanly when the system halts.
This project is split across two repositories by design.
This repository contains the socket implementation and service logic.
Key paths:
-
server/aesdsocket.cTCP socket server implementation (POSIX sockets, syslog, signals, daemon mode) -
server/MakefileSupports both native compilation and cross-compilation usingCC -
server/aesdsocket-start-stopinit-compatible start/stop script usingstart-stop-daemon
To understand how the socket service works, we start here.
This repository is responsible for turning the application into a bootable embedded Linux system.
Key components:
- Buildroot is added as a git submodule (2024.02.x)
- Custom external tree defines the
aesd-assignmentspackage - Cross-compilation and installation of
aesdsocketinto/usr/bin - Init script is installed to
/etc/init.d/S99aesdsocket - Reproducible build scripts:
This is where the application is compiled into a binary and run as a system service.
The aesdsocket service implements the following behavior:
- Opens a TCP stream socket bound to port 9000
- Logs client connections and disconnections using syslog
- Receives data until a newline character is encountered
- Appends completed packets to
/var/tmp/aesdsocketdata - Sends the entire contents of the file back to the client after each packet is written
- Continues accepting connections until interrupted
- On
SIGINTorSIGTERM:- Server stops accepting new connections,
- Closes listening sockets
- Deletes
/var/tmp/aesdsocketdata - Logs
Caught signal, exiting - Terminates
A -d flag enables daemon mode, which forks the process after a successful bind and detaches it from the terminal.
The server uses a fork-per-connection model, allowing multiple clients to be handled concurrently. Access to /var/tmp/aesdsocketdata is synchronized using flock() to prevent file corruption across concurrent processes.
The socket service is integrated into the system using a traditional embedded Linux init workflow:
- Managed via
start-stop-daemon - PID tracked using a pidfile
/tmp/aesdsocket.pid - Installed as
/etc/init.d/S99aesdsocket
This ensures:
- Automatic startup when the system boots
- Graceful shutdown during halt or restart
The Linux image is built using Buildroot targeting AArch64 QEMU.
Image features:
- Custom defconfig derived from
qemu_aarch64_virt_defconfig - Dropbear SSH enabled for remote access
- Port forwarding configured:
- Host 9000 → Guest 9000 (socket service)
- Host 10022 → Guest 22 (SSH)
The system can be built and launched with:
./build.sh
./runqemu.shNo manual interaction is required after the build completes.
The project was validated using both automated and manual testing approaches:
-
Automated scripts
sockettest.shfull-test.sh
-
Manual testing
- Interaction testing using
netcat - Remote access and file transfer verification using SSH and SCP
- Interaction testing using
-
Build validation
- Clean rebuilds tested using
make distclean
- Clean rebuilds tested using
A clean shutdown followed by a restart guarantees that no stale data persists from previous runs.
- Beej's Guide to Network Programming, which is an excellent resource for socket server/client.
- Man pages for accept, bind, socket and start-stop-daemon.
- Busybox Mirror, the original git url sometimes doesn't work!
- For enabling ccache in Buildroot, follow this documentation.