Creating and using a custom OS initialiser.

Share your own howto's etc. Not for support questions!

Creating and using a custom OS initialiser.

Postby edbarx » 2016-06-15 03:52

Contrary to what many might imagine, an OS init is not rocket science but can be implemented under 20 lines of C code. This seemingly impossible feat was accomplished by Rich Felker author of musl libc. The code is as follows:

Source: https://gist.github.com/rofl0r/6168719
Code: Select all
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>

int main()
{
   sigset_t set;
   int status;

   if (getpid() != 1) return 1;

   sigfillset(&set);
   sigprocmask(SIG_BLOCK, &set, 0);

   if (fork()) for (;;) wait(&status);

   sigprocmask(SIG_UNBLOCK, &set, 0);

   setsid();
   setpgid(0, 0);
   return execve("/etc/rc", (char *[]){ "rc", 0 }, (char *[]){ 0 });
}


What does the code do?
First it checks whether the user is root exiting if the user in not root. Then, it blocks all messages before forking the process to produce a child that is used to do the actual OS loading. The fork works as follows: in the calling process, the parent process, fork() returns the non-zero PID of the child while in the newly created child process it returns 0. Execution in the child follows from the same point in the parent. This means, the parent process will enter the infinite loop that repeatedly calls wait(&status) which clears zombies from the kernel's process table completely freeing their resources. In the child, as a result of fork() returning 0, the infinite loops is skipped and the succeeding lines of code are executed. The first instruction is to unblock messages so that newly created processes can communicate. At the end, it calls execve which replaces the child process with a shell that runs /etc/rc. Under Debian the rc script is found under /etc/init.d.

I found using /etc/init.d/rc directly does not successfully load Debian or Devuan provided /etc/init.d is properly filled with scripts and rcN and not emplty. I used a simple shell script to first call "rc S" and then "rc 2". This successfully loaded a useable operating system.

The custom script to load the OS:
Code: Select all
#!/bin/sh

if /etc/init.d/rc S; then
  /etc/init.d/rc 2
fi


I modified Felker's code as follows so that the above script would run. I placed the script under /sbin with all execution bits set using chmod 755 osloader.sh. I named the script osloader.sh.

Modified Felker's C init to load Devuan/Debian provided there /etc/init.d is properly populated and /etc/rcN directories are filled with working symbolic links.
Code: Select all
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>

int main()
{
   sigset_t set;
   int status;

   if (getpid() != 1) return 1;

   sigfillset(&set);
   sigprocmask(SIG_BLOCK, &set, 0);

   if (fork()) for (;;) wait(&status);

   sigprocmask(SIG_UNBLOCK, &set, 0);

   setsid();
   setpgid(0, 0);
   return execve("/sbin/osloader.sh", (char *[]){ 0 }, (char *[]){ 0 });
}
Debian == { > 30, 000 packages }; Debian != systemd
The worst infection of all, is a false sense of security!
It is hard to get away from CLI tools.
User avatar
edbarx
 
Posts: 5397
Joined: 2007-07-18 06:19
Location: 35° 50 N, 14 º 35 E

Return to Docs, Howtos, Tips & Tricks

Who is online

Users browsing this forum: No registered users and 3 guests

fashionable