Привет всем!

В большинстве книг по Linux, ядро — это такая священная корова или, как говорят, "черный ящик". Мы работаем в командной строке, юзаем утилиты, а где-то там, за занавесом, этот ящик творит чудеса, чтобы всё работало.

Я решил сам разобраться и доказать: ядро Linux — это просто исполняемый файл. Никакой магии. Его можно взять, скомпилировать (или просто скопировать) и запустить, как любой другой бинарник.

Сейчас мы проделаем пару простых но крутых экспериментов. Цель не столько повторить их, сколько построить в голове четкую картину, как вообще Linux устроен и как его компоненты общаются.

Но сперва — а что это вообще за ядро?

Коротко о "Мозгах"

Ваш компьютер — это куча железа: процессор, память, сетевуха, видеокарта. Все это добро от разных производителей, и каждое требует своего языка.

Ядро ОС — это посредник.

  1. Оно дает нам единый API для общения с железом. Не надо писать код под NVIDIA, Realtek и AMD одновременно. Мы просто просим у ядра доступ, а оно уже разруливает с конкретным устройством.

  2. Оно — главный диспетчер. Решает, какой программе дать процессорное время, сколько оперативы и какой доступ к файлам.

  3. По сути, ядро — это runtime для всего компьютера.

Где его искать?

Найти ядро легко, оно лежит в /boot. Переходим туда и смотрим:

~$ cd /boot
/boot$ ls -1
System.map-6.12.48+deb13-amd64
vmlinuz-6.12.48+deb13-amd64 # Вот оно!

Наш главный файл — vmlinuz-6.12.48+deb13-amd64. Это и есть сжатый образ ядра.

Кстати, если интересно, что значит имя: vmlinuz — это vm (виртуальная память), linu (Linux) и z (сжатый). А дальше идет версия и архитектура (amd64). В общем, просто имя файла.

Эксперимент 1: Запуск на коленке

Давайте скопируем его и запустим, но не на реальном железе (не хотим ломать основную систему), а внутри QEMU — виртуальной машины-эмулятора.

Подготовка:

~$ mkdir kernel-play
~$ cd kernel-play/
~/kernel-play$ cp /boot/vmlinuz-6.12.48+deb13-amd64


Установка QEMU:

~$ sudo apt update
~$ sudo apt install -y qemu-system-x86 qemu-utils


Запускаем ядро! Даем ему 256 МБ памяти, указываем, какой файл использовать как ядро, и выводим консоль в наш терминал

~/kernel-play$ qemu-system-x86_64
-m 256M
-kernel vmlinuz-6.12.48+deb13-amd64
-append "console=ttyS0"
-nographic


И вот тут начинается самое интересное. Ядро стартует, вываливает кучу логов про инициализацию, а потом... падает с ошибкой:

[ 2.181875] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

Ожидаемо. Ядро запустилось, сделало все свои внутренние дела, а потом говорит: "Окей, я готов. Где моя файловая система и где программа, которую мне надо запустить первой (process init)?" А их нет. Поэтому — паника.

Это отлично доказывает: Ядро — это просто программа, которая выполняет свою часть работы, а потом ждет, что его работу продолжит кто-то еще.

Эксперимент 2: Даем ядру первую программу

Чтобы ядро не рухнуло, нам нужно дать ему минимальный набор файлов, включая ту самую первую программу, которая называется процесс init (PID 1).

Для этого мы сделаем initramfs (Initial RAM filesystem) — временную файловую систему, которая грузится прямо в память, пока ядро не найдет нормальный диск.

Наша программа init на Go Go идеален, потому что делает статические бинарники — им не нужны никакие внешние библиотеки, они работают везде. Я написал простую программу, которая просто печатает "Hello" и "тикает" каждую пару секунд.

# Создаем и компилируем
~/kernel-play$ mkdir init && cd init
# ... создаем файл main.go и компилируем ...
~/kernel-play/init$ CGO_ENABLED=0 go build -o init .

Сборка минимальной ФС Нам нужны каталоги /proc, /sys, /dev и, конечно, наша программа init.

~/kernel-play$ mkdir -p rootfs/{proc,sys,dev}
~/kernel-play$ cp ./init/init rootfs/init
# Создаем нужные узлы для консоли
~/kernel-play$ sudo mknod rootfs/dev/console c 5 1
# ...


Теперь пакуем все это в архив, который и будет нашим initramfs.img:

~/kernel-play$ ( cd rootfs && find . | cpio -H newc -o ) > initramfs.img

Второй запуск! Теперь мы даем QEMU ядро (-kernel), нашу маленькую файловую систему (-initrd) и явно говорим ядру, какую программу запускать первой (rdinit=/init).

~/kernel-play$ qemu-system-x86_64
-m 256M
-kernel vmlinuz-6.12.48+deb13-amd64
-initrd initramfs.img
-append "console=ttyS0 rdinit=/init"
-nographic


Успех!

Ядро снова инициализируется, но в этот раз оно находит нашу initramfs.img и запускает наш Go-бинарник.

...
[ 2.672446] Run /init as init process
Hello from Go init!
PID: 1
tick 0
tick 1
...


Наша простая программа на Go получила PID 1! Это и есть самый первый процесс, который теперь, по идее, должен запускать systemd или sysvinit или что у вас там — то есть все остальное, что нужно для работы ОС. Мы только что сделали свою, пусть и крайне примитивную, но рабочую сборку Linux.

Выводы, которые теперь стали очевидны

  1. Ядро — всего лишь файл, который грузится первым и инициализирует железо.

  2. Дистрибутив Linux — это просто ядро, к которому прикрутили набор утилит и конфигурационных файлов (наш Go-файл и rootfs).

  3. PID 1 — это всегда первый процесс, который запускает всё.

  4. Всё, что до запуска init — это пространство ядра (Kernel Space). Всё, что после — пользовательское пространство (User Space), где работают все наши приложения.

Черный ящик стал прозрачным. Это просто код, который можно собрать и запустить.

Комментарии (9)


  1. bighorik
    13.01.2026 07:33

    Это просто код, который можно собрать и запустить.

    Ого, а я думал, что Линукс - это когда ты с флешки загоняешь в комп отряд Фиксиков, и они там своими помогаторами начинают гонять электроники туда сюда, и поэтому все работает.

    Спасибо, открыли глаза.

    Идеи для следующих статей:

    1) доказать, что вода - мокрая, а не красная

    2) что собаки лают горлом, а не задницей

    3) что брить мошонку зажигалкой эффективно с точки зрения временных затрат

    Если серьезно, то попробуйте в следующий раз перед написанием статьи открывать первую ссылку в гугле


    1. RavenStark
      13.01.2026 07:33

      Да ладно вам, нормально. Множество людей, которые с линуксом не особо знакомы за пределами использования графического интерфейса, примерно так (о фиксиках) и считают. А тут хотя бы на очень простом и понятном уровне рассказано, что это за зверь, что за PID 1, на кой фиг он нужен. Неплохо для начала.


      1. furvionx
        13.01.2026 07:33

        надо им просто один раз показать как собирается очередное/новое ядро без перезапуска системы и далее всё продолжает работать как-будто ничего не было - сразу всё поймут и про фиксиков


        1. RavenStark
          13.01.2026 07:33

          Это позже. А то как раз и скажут "колдун е..."


    1. PrincePercia Автор
      13.01.2026 07:33

      Спасибо за конструктивную критику! Я понимаю, что для таких гуру, как вы, ядро Linux это пройденный этап. Но, как показывает практика, многие новички застревают именно на этапе абстракций, и разложить всё по полочкам на практике гораздо полезнее, чем в сотый раз отправлять людей в гугл.

      Кстати, заглянул в ваш профиль. Очень впечатлила статья про "дендро-фекальные технологии" в модификации кресла. Теперь я понял: доказывать, что ядро это файл, это "вода", а вот прикрутить кусок фанеры к стулу с помощью дверных петель и ножовки по металлу это, безусловно, прорыв в High-Tech, достойный главной страницы.

      Кто-то объясняет архитектуру систем, а кто-то борется с локтями при помощи шкантов и алюминиевого профиля. Удачи с модернизацией, не забудьте про наждачку в следующий раз!


      1. bighorik
        13.01.2026 07:33

        Отнюдь, я тот еще чайник, и стараюсь линух стороной обходить. Моя претензия строго ограничена поставленным в статье вопросом и ответом на него.

        Компьютер выполняет программы за электричество, а не кастует спеллы за ману, об этом еще дед Фортран в советском учебнике рассказывал.

        Касательно статьи про кресло:

        1) лайк за королевский черри-пиккинг

        2) статья подавалась, как юмористическая, и ставила перед собой именно такую цель. Если называть статью по аналогии с вашей, тогда получилось бы что-то вроде "кресло - реально ли просто штука для посидеть?", затем абзац мол "мы попытались сесть, и действительно, мы смогли сесть! Это доказывает, что кресло - штука для посидеть!", затем еще абзац "мы посидели еще, и так и не упали - еще оно доказательство в копилку нашей теории"

        Если вы хотели написать статью для молодых и зеленых, то обозначайте это именно так. Если бы изначальный вопрос был бы поставлен как нибудь типа "ядро линукса для самых маленьких/для чйников", "ядро линукса на пальцах" или "ядро линукса не такое страшное, как может казаться" - было бы ровно 0 вопросов, но в текущей постановке это хуже, чем первая ссылка в гугле


  1. homm
    13.01.2026 07:33

    Статья офигенная! На таком просто примере показывает за что ядро отвечает и что ему нужно для работы.


    1. dlinyj
      13.01.2026 07:33

      Не увидел за что отвечает ядро, а особенно что ему нужно для работы.


  1. dlinyj
    13.01.2026 07:33

    Забавная статья, я бы сказал именно забавная. Есть ряд дополнение и замечаний:

    1. Ядро может быть где угодно, и не обязательно в /boot. Во встраиваемых системах оно может лежать в области ПЗУ (например в разделе NAND и не быть видным из файловой системы), загрузчиком типа u-boot распаковываться в ОЗУ и передавать ему управление.

    2. Статическая компиляция есть и в Си, можно прилинковать статические библиотеки, это часто используется если libc на целевой системе не совместима. В принципе тут можно написать мейкфайл.

    3. На мой взгляд, статья неполноценна в том смысле что это запускается в qemu, и там проходит очень много за кадром, как ядро загружается и инициализируется. А кухня там будь здоров, тут вспомнить пред загрузчик, загрузчик, при этом цепочка может быть весьма большая (тут можно вспомнить BIOS, GRUB и иже с ним, на каждой системе свои погремушки). И без загрузчика ядро не запустить. А загрузчик берёт этот архив, распаковывает его в ОЗУ и передаёт ему управление.

    4. Мне не хватило самого главного: если это программа, то пару слов как её собрать, модифицировать и запустить.

    Итого, я согласен с первым комментатором.

    P.S. И где код на гоу, а то это "как нарисовать сову".