Вот вполне книга,
http://www.linuxfromscratch.org/Коротко, как происходит загрузка,
Загрузчик копирует образ ядра по некоторому адресу, делает возможно ещё какие то действия (передача параметров, например диапазон адресов RAM) это платформо-специфично, подробности должны быть в документации вместе с исходниками ядра. Загрузчик передает упрвленияе ядру, ядро инициализируется, после чего важный этап это монтирование корневой файловой системы, нужно либо иметь драйвер устройства на котором будет фс, либо сделать initrd, это корневая фс которая хранится в RAM, загрузка образа initrd производится загрузчиком. В корне ищется бинарник init (обычно /sbin/init) и запускается. Далее init производит инициализацию user space, обычно это предствалено шелл скриптом и туда можно вписать все что нужно. Все дальнейшие действия сильно зависят от того что вам надо и легко перенастраиваются, обычно дальше идет запуск login (getty) процессов для терминалов.
Образы программ в формате ELF представлены файлами на фс, и могут быть запущены (т.е. создан соответствующий им процесс) с помощью системных вызовов из уже работающих процессов. Как конкретно производится системный вызов и передача/возврат параметров отностися к ABI.
Драверы либо вкомпиливаются в ядро, либо создается модуль который можно загрузить и выгрузить в любой момент в работающей системе. Выбрать это все можно при конфигурировании ядра.
Для кнопок и меню, да нужен софт это реализующий.