*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

воскресенье, 8 марта 2009 г.

Загрузка Linux без ядра за 25 секунд

Естественно, загрузиться Linux совсем без ядра не может. Но он может загрузиться не имея в начале процесса загрузки ядра в двоичном виде. А откуда же берется ядро? Ядро компилируется прямо при загрузке!

Вы думаете, такая загрузка будет длиться годы? ну или хотя бы минуты? Нет. На все про все — 25 секунд с хвостиком.

Итак, по порядку.

Все знают QEMU — бесплатная виртуальная машина. Из нее, например, вырос пакет VirtualBox, а KVM унаследовал интерфейс командной строки. Это чистый виртуализатор без всяких там “пара-” приставок. Из-за этого работает небыстро и для критичных по скорости задач слабо применимо, но с другой стороны из-за “чистоты” виртуализации работает на многих платформах и виртуализирует многие платформы, а не только Intel, как большинство “быстрых” виртуальных машин. Из-за все сказанного, QEMU идеален для всякого рода экспериментов и нестандартных задач.

Но мы отвлеклись. Автор QEMU — Fabrice Bellard — написал еще нескольно занимательных программ.

Одной из них является TCC — Tiny C Compiler. Это ультра быстрый и ультра маленький компилятор С. Сразу возникает подозрение — слово “tiny” в название, да еще и “ультра быстрый” и “ультра маленький”. Главный вопрос — какие у него ограничения?

Как заявляет автор, TCC полностью поддерживает стандарт языка С вплоть до ISO C99 включительно, но целевая платформа только x86. Компилятор имеет также мини версию системной библиотеки libc. Когда это возможно, компилятор совмещает фазы компилирования, ассемблирования и линковки для дополнительного ускорения, хотя поддерживаются стандартные ABI и можно подлинковать что-то готовое.

Компилятор доступен в исходных текстах и в двоичном виде под Windows. Скомпилировать его можно вручную, например, самим же TCC.

Нужно на чем-нибудь проверить TCC, на чем-нибудь нетривиальном. Ядро Linux'а является весьма сложным и большим проектом, это его сборка была бы отличной проверкой.

TCC не только успешно собирает ядро, но и делает это до 9 раз быстрее, чем GCC (естественно, речь идет только о платформе x86).

Невероятная скорость компиляции позволяет использовать TCC как компилирующий “интерпретатор” скриптов. Если добавить первой строкой вашей программы на С строчку “#!/usr/local/bin/tcc –run” и установить флаг “executable” на исходник, то ваша программа будет запущена в UNIX’е прямо из исходного текста, будучи скомпилированной на лету.

Мы подходим к сути. Автор предлагает вариант загрузки Linux, когда ядро компилируется прямо в процессе загрузки из исходных текстов. Проект называется TCCBOOT. Можно скачать ISO имидж (около 6 мегабайт), записать на болванку, загрузиться с нее и увидеть все самому. Что я и сделал.

Загрузчик ISOLINUX запускает мини образ, в котором содержится TCC, исходники ядра и минимальное окружение для запуска командного интерпретатора под скомпилированным на лету ядром.

Поехали…

Старт, запустился ISOLINUX, началась компиляция ядра:




Все, за 25.4 секунды ядро скомпилировано, запущено, и загружена минимальная UNIX система:



Фотографии я делал с рук, так что немного коряво выглядит. Можно было, конечно, все это проделать под виртуальной машиной, тогда бы и скриншоты были бы красивее, но пропало бы ощущение самого главного — чудовищной скорости. Забавно, на первом снимке видно, что строка отображения имен компилируемых файлов смазана — так все “летает”.

Эксперимент проводился на ноутбуке Core 2 1GHz, 2GB RAM.

Я был очень впечатлен. А если в TCC нормально поддержать многопроцессорность? Тут недалеко и до полностью функциональной операционной системы, у которой нет двоичного представления до загрузки.

4 комментария:

  1. Да уж, респект автору компилятора и софтрварной реализации TinyGL. Глянул исходники компилятора и TinyGL. Скомпилил fib.c. Windows версии программ не слинковались, не стал разбираться, наверное если полсунуть бибилиотеки от mingw может и заработает. Ну компилятор видно действительно маленький, к примеру компилит случай потенциально деление на ноль
    т.е.
    int x = 1 / 0;
    fprintf(stderr, "%d", x);
    но без вывода в консоль он не использует переменную x.

    ОтветитьУдалить
  2. При такой скорости компиляции может проще все заново пересобрать, чем линковать.

    ОтветитьУдалить
  3. Просто двоичные модули от майкрософта, видимо, не слинковались в tcc. Может ABI другой.

    ОтветитьУдалить