Pull to refresh

О замене стандартного /sbin/init

Reading time 4 min
Views 12K
init — первый пользовательский процесс в Unix-подобных операционных системах
init — запускается непосредственно ядром системы.
init — является пра-родителем всех пользовательских (userspace) процессов системы.

Стандартный /sbin/init читает конфигурационный файл /etc/inittab, стартует систему и управляет системой используя несколько «уровней исполнения» (runlevels).

С помощью одноименного ключа init можно сказать ядру Linux использовать другой файл, вместо стандартного /sbin/init

Воспользуемся этой возможностью и добавим следующую конфигурацию в /boot/grub/menu.lst
title Linux kernel and custom init
root (hd0,1)
kernel /linux/vmlinuz-2.6.26-1-686 root=/dev/hda2 init=/linux/init
initrd /linux/initrd.img-2.6.26-1-686

Кто пользуется возможностью подменить процесс init? Иногда к этому прибегают разработчики встраиваемых систем — таким способом можно упростить разработку устройства и не тащить за собой всё окружение операционной системы.

В моём случае желание подменить init лежало в другой плоскости — хотелось проверить как поведёт себя процесс init системы Xameleon исполняемый Linux ядром. Желаете попробовать тоже?

Как я менял стандартный /sbin/init на Xameleon init. (исходный код и описание)

Для сборки проекта воспользуемся любым современным дистрибутивом Linux с установленными средствами разработки gcc. Напишем простейший Makefile:
PROGRAM= init

SRCS= init.cc

LDFLAGS+= -static
LIBS+= -lc

all:
g++ -D POSIX -D LINUX $(CFLAGS) $(SRCS) $(LIBS) $(LDFLAGS) -o init


Собственно, дальше статью можно не читать — почти любой исходный код собранный таким образом можно использовать как замену init. Для любопытных читателей выкладываю исходный процесса init операционной системы Хамелеон. Это специфический процесс init — его можно использовать как единственный процесс операционной системы — он содержит примитивнейший интерпретатор нескольких команд и возможность запустить процесс.

Во время продумывания статьи меня терзали сомнения — под какой лицензией выложить код init. После долгих и мучительных раздумий выбор пал на Two Clause BSD License.

История этого исходника проста — он создан для операционной системы Хамелеон и ныне используется Хамелеоном по назначению. Недавно пришла идея — почему бы не попробовать свою версию init в Linux? Эдакий тест на совместимость.

typedef struct typeCommandEntry
{
	const char		*	szCmd;
	int				nLength;
	int				(*fHandler)( int argc, char * argv[], char * envp[] );
	const char		*	szHelpString;
} typeCommandEntry;

///////////////////////////////////////////////////////////////////////////////
// Callback's array
//
static typeCommandEntry	CommandList[] =
{
	{ "help",		0, tcmdHelp, "Show list of built-in commands. Use 'help command-name' to see detail description of the command-name argument." },
	{ "exec",		0, tcmdExec, "Execite file. Please note that this command overwrites current process by new executable image" },
	{ "info",		0, tcmdSysInfo, "Show some information from the L4 KIP" },
	{ "memmap",		0, tcmdMemMap, "Show a kernel memory map" },
	{ "modules",		0, tcmdShowModules, "Show registered drivers" },
	{ "term",		0, tcmdDestroyProcess, "Destriy the init process" },
	{ "fork",		0, tcmdForkProcess, "Forks (creates copy of) the init process to another console." },
	{ "wait",		0, tcmdWaitProcess, "Waits for the process termination" },
	{ "kill",		0, tcmdKillProcess, "Sends signal to the process" },
	{ "trap",		0, tcmdTrapProcess, "Sends the trap signal to the process" },
	{ "reset",		0, tcmdReset, "Reset current console to the initial state" },
	{ "mount",		0, tcmdMount, "This command shows mounted filesyetems if used without arguments.\nUse 'mount device  mount-point' to mount device into filesystem tree." },
	{ "umount",		0, tcmdUnmount, "Unmounts filesystem that provided as command argument. " },
	{ "cd",			0, tcmdChangeDir, "Change current directory" },
	{ "dir",		0, tcmdShowDirectory, "Show directory without parsing inodes" },
	{ "ls",			0, tcmdListDirectory, "List files into current directrory or files that reside to a path provded as command argument" },
	{ "chroot",		0, tcmdChangeRootDirectory, "Changes the root directory of the caller process." },
	{ "cat",		0, tcmdShowFile, "List file on active console" },
	{ "rm",			0, tcmdRemoveFile, "Remove file" },
	{ "rmdir",		0, tcmdRemoveDirectory, "Remove directory" },
	{ "mkdir",		0, tcmdMakeDirectory, "Create directory" },
	{ "ln",			0, tcmdMakeLink, "Link the file inode as a new file" },
	{ "mv",			0, tcmdMoveFile, "Moves file into another place. Please note that this command able to move files within same filesystem." },
	{ "df",			0, tcmdDiskInformation, "Show mounted partitions information" },
	{ "chown",		0, tcmdChangeOwner, "Chane owner of file or directory" },
	{ "sync",		0, tcmdFlushCaches, "Flush disk caches" },
	{ "cp",			0, tcmdCopyFile, "Copy file" },
	{ "setenv",		0, tcmdSetEnvironment, "Set environment variable" },
	{ "getenv",		0, tcmdGetEnvironment, "Get environment variable" },
	{ "unsetenv",		0, tcmdUnsetEnvironment, "Unset environent variable" },
	{ "pwd",		0, tcmdPwd, "Print working directory" },
	{ "dump",		0, tcmdDump, "Show file/device hex dump" },
	{ "env",		0, tcmdEnv, "Show current environment" },
	{ "exit",		0, tcmdExit, "Terminates init process. This command have no meaning in production sysstem, but usefull for debugging)" },
	{ "quit",		0, tcmdExit, "A synonym for the exit command" },
};


Например, чтобы запустить стандартный shell используйте команду
/#exec /bin/sh

Чтобы выключить компьютер
/#exec /sbin/halt

Извините за плохой английский в коде — сообщения на русском были бы лучше, но на этапе исполнения процесса init русский знакогенератор ещё не загружен — это забота потомков первого процесса.
Принимаю патчи.
Не пробовал под FreeBSD. Если вдруг не соберётся — пишите.

Скачать исходный код xameleon init

http://narod.ru/disk/26585438001/xam_init.tgz.html

Приятного make.
Tags:
Hubs:
+3
Comments 16
Comments Comments 16

Articles