17

I'm trying to run a Linux application and all I want to run is this one application off of boot. I need networking and that's all (no display, peripherals, etc.). I want no other applications running so that the application I run has 100% of the CPU. Is this possible?

  • It won't be able to grab 100% of the CPU seeing as your OS still needs some resources. – n0pe Aug 8 '11 at 17:44
  • @MaxMackie Obviously, but I would like the OS to only take over on behalf of the application (for networking purposes for instance). – dschatz Aug 8 '11 at 17:45
  • 1
    You realize that even with a desktop environment loaded, but sitting there idle, it isn't using any cpu time right? And the ram it is using is subject to being swapped out if other applications demand it. – psusi Aug 8 '11 at 18:28
  • @dschatz It would help if you include more details in your question. Like telling us more about what application you want to run, how you want it to perform and what kind of hardware you're using. – N.N. Aug 8 '11 at 21:17
  • If possible, I would like to know why do you want this. From what I understand, you want to remove everything from the OS (console included) just to run your app. The performance gains will be marginal so what is the point of having all that work? – nmat Aug 8 '11 at 21:22
13

Minimal initrd CPIO hello world program step-by-step

enter image description here

Compile a hello world without any dependencies that ends in an infinite loop. init.S:

.global _start
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $message, %rsi
    mov $message_len, %rdx
    syscall
    jmp .
    message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
    .equ message_len, . - message

We cannot use sys_exit, or else the kernel panics.

Then:

mkdir d
as --64 -o init.o init.S
ld -o init d/init.o
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"

This creates a filesystem with our hello world at /init, which is the first userland program that the kernel will run. We could also have added more files to d/ and they would be accessible from the /init program when the kernel runs.

Then cd into the Linux kernel tree, build is as usual, and run it in QEMU:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"

And you should see a line:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

on the emulator screen! Note that it is not the last line, so you have to look a bit further up.

You can also use C programs if you link them statically:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}

with:

gcc -static init.c -o init

You can run on real hardware with a USB on /dev/sdX and:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX

Great source on this subject: http://landley.net/writing/rootfs-howto.html It also explains how to use gen_initramfs_list.sh, which is a script from the Linux kernel source tree to help automate the process.

Next step: setup BusyBox so you can interact with the system: https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902

Tested on Ubuntu 16.10, QEMU 2.6.1.

| improve this answer | |
3

you can start kernel with init=/path/to/myapp parameter defined in your bootloader.

| improve this answer | |
  • 2
    This is a rather extreme solution. Replacing the startup script with the user application will have the application running without networking, without any filesystems other than the rootfs mounted (no sysfs or proc or tmpfs), and possibly some device nodes will not be created. – sawdust Aug 9 '11 at 15:33
  • 2
    @sawdust: Totally agree. But the question was also bit extreme... :-) – Michał Šrajer Aug 9 '11 at 17:05
2

It sounds like you are trying to set up a kiosk. Most guides around the Internet focus on a web browser like Firefox as the single application that runs. Take a look at this guide for ideas.

| improve this answer | |
  • 2
    Hmm, I'm really just trying to run a single application with networking. I don't want any X and as few other applications running as possible. I don't see how this restricts all the unnecessary daemons from running. – dschatz Aug 8 '11 at 17:43
  • can the application run without X though? – Journeyman Geek Dec 6 '11 at 3:37
2

You can certainly run just one user application after booting the kernel. But it will not have 100% of the CPU because there will be some other kernel-related processes that must exist. This is commonly done in embedded-Linux devices, e.g. wireless routers. I also have first-hand experience doing this for a multi-threaded application.

Once the kernel has booted, an initialization or startup script is run. Read up on Linux runlevels and the init process. There are various startup schemes in use, so it is not possible to be specific. But Linux will allow you to configure exactly which applications and daemons will execute for your situation. Other than a startup file at root, the files that need modifying are in /etc, and in particular /etc/init.d

BTW unless you're somekind of superprogrammer or before you get a remote GDB server running, you're going to need somekind of debug console (either the PC console or a serial port) for your application. This will allow you to be notified of seg faults, bus errors and assertion failures. So plan on having somekind of "peripheral" besides "networking".

| improve this answer | |
1

There are some system applications which are must be run, besides them, sure, you can dedicate the rest of the computer resources to that application. To have the very minimum you can take a look at really small Linux distros like TinyCore Linux etc.

Also it would depend on application itself too, what services it requires besides the network etc.

I think if you can provide more specific information you would get more detailed response.

Like what kind of app etc.

| improve this answer | |
  • My application uses the pthread library to run some mulithreaded workload (arithmetic operations) and can be instructed to do different calculations based on input from tcp/ip. Looking at TinyCore Linux, it boots into a full desktop environment, which I don't want. – dschatz Aug 8 '11 at 17:36
  • TinyCore has a smaller brother called MicroCore. No GUI, check it out. – n0pe Aug 8 '11 at 17:45
  • 1
    @MaxMackie I actually want no interface on the machine itself outside of the tcp/ip stack. The application can block on a port and can be controlled via tcp packets sent to that port. – dschatz Aug 8 '11 at 17:55
  • 1
    I'd recommend an environment with little services running (check this out linuxhelp.blogspot.com/2006/04/…) and hardly anything other than your application and it's dependencies installed. – n0pe Aug 8 '11 at 18:01
  • 1
    @dschatz well, then you need to hack kernel, remove everything else and compile your app into it. no bash no anything else. just your app..lol. – bakytn Aug 8 '11 at 18:33
0

If you really want nothing but the Linux kernel, networking, and your application, the only way to do it is this:

  • You will need to make your application a kernel module - make sure it is debugged and well tested. This kernel module would have to initialize things typically done via userspace such as set interface IP addresses and all that good stuff.
  • You will need to download and configure (make menuconfig) your own custom kernel and remove all features that are not related to running the system and networking. You will want to disable to block layer, I don't know how to do this on recent kernels through make menuconfig.
  • You then need to include your module into the kernel so it is included as part of the kernel and not a loadable module. You would likely disable loadable modules in the step above. If you know enough C/C++ to create a kernel module this should be easy for you.
  • You need to modify whatever part of the kernel that panics if init fails to not do that, or be prepared to live with 1 extra user-space process.

I know it's possible for kernel modules to create processes - a simple ps aux would show many on a typical system (they are all in brackets). You probably want your module to create a kernel process. To get rid of all kernel-created processes besides yours, you'll need to disable threads [kthreadd], power management [pm], the event layer [events], and others.


If you want a more practical setup of the kernel + 1 user space process, that's possible.

Linux has a kernel command line option called init= - this is what the kernel will start when it's done loading. The program must be on the root device that is specified with root= or in the initrd (loaded by your bootloader).

If this program exits, Linux will panic, so make sure it doesn't ever exit.

Many modern distributions of Linux have it setup so an init program in the initrd does some additional user-space initialization, before starting /sbin/init or /sbin/systemd. You'll have to find out what your distro does here (info for Debian is here) and find where you can specify the final "handoff" program, and from there you can tell it to start your application instead of init or systemd.

systemd manages a lot of basic functionality, like building /dev, setting hostname, and other things, so if you are flexible you may want to instead look into configuring systemd to spawn a single process, and optionally restart it if it fails. If I am not mistaken it basically does this for single-user or recovery mode - it starts a shell.

You'll have 2 processes running (systemd and your program) but the system won't panic if your program exits or crashes.

Consider also simply a lightweight install of Debian - a "netinst" install doesn't have much running other than the kernel, a shell, and a couple services - or consider OpenWRT/LEDE - it has a webserver for Luci running by default and a couple other services but is easily disabled.

| improve this answer | |
  • You also probably want to look into unikernels which actually implement this concept. – LawrenceC Aug 12 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.