I am wondering how I could go about creating my own "custom" Linux distro that will run just one program, pretty much exactly the same way as XBMCbuntu. I'm not asking for a step by step guide, just maybe a link to something that can help me on my way.

  • Welcome on U&L, please take a guided tour and take the time to learn how to ask a question what do you want to do ? because the definition of application is pretty vague and does not mean nothing at all, because my advise would be to use busybox but that's probably not what you want. so please, take the necessary time to express your need and we might be able to help you. Do not hesitate to edit your question to add any relevant element in it. – Kiwy Apr 2 '14 at 9:19
  • 1
    Seems pretty clear to me... – goldilocks Apr 2 '14 at 10:03
  • @TAFKA'goldilocks' well no, because I bet you can still have access to a terminal or something similar on XBMCubuntu while it seems only one app is running graphically,but notonly one app is running. I have made a small distro once from scratch with only a kernel and busybox, in that case, even if there is services that are launch by the kernel, you can say busybox is your only app. – Kiwy Apr 2 '14 at 10:34
  • @Kiwi That's a good answer then (better than LFS). Keep in mind: 1) This question may be useful to other people whose general purpose is the same, so a range of answers is good, 2) While there is a range of possible solutions here -- i.e. TIMTOWTDI -- and some may be better suited to some more specific goal than others, I am pretty sure they will all work and a significant aspect of deciding on a solution will be subjective (e.g., because of the OP's prior knowledge and experience, not the objective nature of the task). – goldilocks Apr 2 '14 at 10:49
up vote 5 down vote accepted

I would not start messing with LFS, that is a garden path leading to some dark woods.

Start with a distro where you have a lot of control over the initial install, such as Arch, or a headless edition such as Ubuntu server. The point of this is not so much to save space as to delimit the complexity of the init configuration; starting from a headless distro, if the application you want to run requires a GUI, you can add what's required for that without having to end up with a GUI login (aka. the display manager or DM) started by init, and a fullblown desktop environment to go with it.

You then want to learn how to configure the init system to your purposes -- note that you cannot do without init, and it may be the best means of accomplishing your goal. There are three variations on init commonly used on linux (but there are some others):

  • Debian uses a variation on the classic Unix SysV style init. As of thejessierelease, Debian has also switched tosystemd (https://wiki.debian.org/systemd)

  • Ubuntu and derivatives use upstart.

  • Fedora, Arch, and derivatives use systemd.

If you don't know anything about any of these yet, none of them is particularly harder to use than any of the others. If you go with one of the later two, they provide some mechanisms for backward compatibility with SysV, but do not bother with that, it is NOT any simpler.1

The point here is to minimize what init does at boot, and that is how you can create a system that will run a minimal amount of software to support the application you want to focus on -- this is essentially how a server is set up, BTW, so it is a common task (note that you can't literally have "just one" userland process running, at least not usefully).

If the application you want to run is a GUI program (a good example of why you can't literally just run one application, since GUI apps require an X server), you can have an ~/.xinitrc that looks like this;

#!/bin/sh

myprogram

When you then startx, your program will be the only thing running, and it will be impossible to change desktops or start anything else, partially because there is no window manager or desktop environment (hence, there will be no window frame or titlebar either).

1. To belabour the point a bit: When you are researching this, you may find some griping about systemd and upstart from people who were previously familiar with SysV claiming, e.g., that they are too complicated. However, objectively they are not any more complex than SysV (IMO systemd is simpler to use, in fact), but most dogs prefer their old tricks, so to speak. This griping is starting to die down now both systems have been in use for a while.

  • 1
    You can't do without init but certainly you can do without upstart, systemd, or sysv. init is just some executable file named init that your kernel invokes when it mounts initramfs. In most cases these other three aren't even init but they're actually execed into by init, which is commonly busybox. – mikeserv Apr 2 '14 at 11:33
  • @mikeserv Absolutely (and I did explicitly mention that these are not the only three choices). Note also that I deliberately excluded busybox because that deserves separate treatment in a separate answer, but not by me. – goldilocks Apr 2 '14 at 12:21
  • How gracious of you to offer! But no damn way. – mikeserv Apr 2 '14 at 12:22
  • It would be interesting to know if this approach actually works in practice. Anyone actually tried it? – Faheem Mitha Apr 2 '14 at 19:43
  • @FaheemMitha If you mean what I'm recommending here (customize the init configuration), of course it does -- that's how the system already works, you'd just be producing a stripped down and simplified version (I'm sure this is what XBMCbutu is). If you mean, replacing init with some more specialized executable ala busybox, it's probably more trouble than it's worth unless you must do it that way -- the main purpose of busybox is for use in tiny embedded environments (with, e.g., only a few MB of RAM). – goldilocks Apr 2 '14 at 20:53

Minimal init 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 the exit system call, or else the kernel panics.

Then:

mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o      # link
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

Dynamic linking would require setting up a the dynamic linker executable, the most common of which are part of C standard libraries like glibc.

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: Tech Tip: How to use initramfs | landley.net 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://github.com/cirosantilli/linux-kernel-module-cheat

Tested on Ubuntu 16.10, QEMU 2.6.1.

if you are little bit in programming and you want create it from scratch you can go with LFS i.e. Linux from Scratch http://www.linuxfromscratch.org/

if you want to customize ubutnu you can use ubunt-builder and if you want it on rpm base you can use SUsE-Studio,Suse studio will allow you to make custom suse linux

cheers

It is more about what your "one program" requires.

You can still have a good start of understand how to put things together by building an LFS (aka "Linux From Scratch") . Then you will add things required by your program or go for a full distribution because building heavy sub-system like Gnome or KDE on LFS can be a real pain-in-the-ass.

Of course going backward may be easier at first, but removing things from a full distrib can be troublesome: do this in a VM and do copy of this VM at every step.

(my 2 cents)

Edit:

As pointed out by SecurityBeast instead of starting from a full distribution like CentOS or Ubuntu, you may also have a look at building distribution tools like:

What you need to ask is what does your "one program" need and what resources do you have.

If it needs a wide selection of libraries and support binaries you may be best off using a "regular" linux distro (Debian or similar) and just messing with the boot process a bit.

If it needs a narrower selection of support stuff but still requires stuff like networking or support for a variety of hardware using different kernel modules or userland support bits and you don't want the disk space overhead of a regular distro then I would suggest looking at embedded distros (buildroot or similar) or maybe a linux from scratch approach (though that can be a maintainance headache)

If you need just what a non-modular kernel can provide and nothing else then running your own binary straight on the kernel may work and be the lightest soloution..

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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