Search code examples
processoperating-systemstartup

What is the most minimalistic way to run a program inside an OS?


Generally, when I start a program from bash, it forks bash and inherits many things from it, like stdin, stdout. Is there some other way to run a program, with no such setup? Maybe it explicitly opens fd 1, writes something and closes it?

I came across nohup and disown. But both of those detaches a running process from bash, but initially still the process inherits from bash. Maybe is there a way to start a process that inherits from nothing?

I am asking this just out of curiosity, and have no practical purposes. When a program is ran in a microcontroller, it is just our program that is running with no additional setup (if setup is required, user have to prepend it). Similarly, is there a way even in the presence of an operating system, to run just what is programmed, without any setups?


Solution

  • I assume you are using Linux.

    Printing top -u root you see for eg on my system (Ubuntu 20.04 x86_64):

        PID    PPID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
          1       0 root      20   0  170380  11368   6500 S   0.0   0.0   0:23.52 systemd
          2       0 root      20   0       0      0      0 S   0.0   0.0   0:00.61 kthreadd
          3       2 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp
          4       2 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_par_gp
          5       2 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 netns
         10       2 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 mm_percpu_wq
         11       2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 rcu_tasks_rude_
         12       2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 rcu_tasks_trace
         13       2 root      20   0       0      0      0 S   0.0   0.0   0:04.48 ksoftirqd/0
         14       2 root      20   0       0      0      0 I   0.0   0.0   1:28.82 rcu_sched
    

    You see that all processes inherit ultimately from PPID (parent process ID) zero.

    This process is not a process, it represents the Linux scheduler. Then systemd (PID 1) is launched by the kernel and every other process in the system is launched by systemd.

    At a user level top -u madfred

       3371       1 madfred   20   0   19928   7664   6136 S   0.0   0.0   0:11.62 systemd
       3372    3371 madfred   20   0  170404   2460      0 S   0.0   0.0   0:00.00 (sd-pam)
       3379    3371 madfred   39  19  659828  16348  12500 S   0.0   0.0   0:02.38 tracker-miner-f
       3402    3371 madfred   20   0    8664   5112   3412 S   0.0   0.0   0:00.94 dbus-daemon
       3407    3371 madfred   20   0  239712   6740   6064 S   0.0   0.0   0:00.03 gvfsd  
    

    There is one user systemd that is launched by the root systemd and runs as the user. This user systemd is in charge of launching every process for that user.

    That is necessary for assuring all the guarantees that the Linux OS provides as security, memory protection, file resources etc.

    What you want would be to replace the kernel with something else, which is very possible. Check for example:

    https://wiki.osdev.org/Bare_bones

    https://github.com/contiki-ng/contiki-ng

    It is pretty easy to replace systemd (or the old /sbin/init) with your own custom initializer. Check this answer:

    Writing my own init executable