Как сделать свое ядро

Добавил пользователь Владимир З.
Обновлено: 09.09.2024

Вопрос ковыряния ядра Linux впервые поднимался в этом блоге еще в далеком 2016-м году. Мы научились собирать ядро из исходников и цепляться к нему отладчиком. Но на этом все и заглохло. Тогда найти актуальную информацию по разработке ядерного кода в Linux, да еще и в удобоваримом виде, было проблемой. Я предпочел дождаться появления свежих книг по теме, а пока заняться изучением чего-то другого. И вот, спустя пять лет, такие книги были опубликованы. В связи с чем я решил попробовать написать пару модулей ядра, и посмотреть, как пойдет.

Проводить эксперименты было решено на Raspberry Pi 3 Model B+. На то есть три основные причины. Во-первых, малинка широко доступна и стоит недорого (особенно третья малинка, после выхода четвертой), что делает эксперименты повторяемыми. Во-вторых, запускать модули ядра на той же машине, где вы их разрабатываете, в любом случае не лучшая затея. Ведь ошибка в ядерном коде может приводить к какими угодно последствиям, не исключая повреждения ФС. И в-третьих, в отличие от виртуальной машины, малинка не отъедает ресурсы на вашей основной системе и позволяет реально взаимодействовать с реальным железом.

Образ системы был записан на SD-карту при помощи Raspberry Pi Imager. Приложение использовало образ на основе Raspbian 10 с ядром Linux 5.10. Это LTS-версия ядра, поддержка которого прекратится в декабре 2026-го года.

Для написания модулей ядра необходимо установить пакет с заголовочными файлами. В Raspbian это делается так:

В других системах пакет может называться linux-headers-* или как-то иначе.

Создадим новую директорию с файлом hello.c:

int init_module ( void ) <
pr_info ( "Hello world \n " ) ;
return 0 ;
>

void cleanup_module ( void ) <
pr_info ( "Goodbye world \n " ) ;
>

Рядом положим файл Makefile:

obj - m += hello . o

all :
$ ( MAKE ) - C / lib / modules /$ ( shell uname - r ) / build M =$ ( PWD ) modules

clean :
$ ( MAKE ) - C / lib / modules /$ ( shell uname - r ) / build M =$ ( PWD ) clean

Говорим make . В результате должен появиться файл hello.ko.

Теперь попробуем следующие команды:

При загрузке модуля будет вызвана процедура init_module() , а при выгрузке — cleanup_module() . Они напишут соответствующие логи через pr_info() , и мы увидим их в /var/log/syslog. С этим все понятно. Давайте перейдем к чему-то поинтересней.

Начнем с более детального рассмотрения pr_info() . Среди символов, экспортируемых ядром, вы его не найдете. Поиск по заголовочным файлам показывает, что на самом деле это макрос, объявленный в linux/printk.h:

А вот printk() уже является экспортируемым символом:

$ sudo cat /proc/kallsyms | grep 'T printk'
.
801833e0 T printk_nmi_direct_exit
809f1508 T printk
809f16f4 T printk_deferred
.

Первая колонка — это адрес символа. Он отображаются, только если читать /proc/kallsyms под суперпользователем. В противном случае, мы увидим нули. Во второй колонке показано, откуда экспортируется символ. Согласно man nm , T и t соответствуют секции кода (.text). Заглавная буква означает, что символ виден глобально, а значит, может использоваться в модулях ядра. Теперь мы чуть лучше понимаем, как происходит общение между ядром и его модулями.

Далее, рассмотрим модуль посложнее:

MODULE_LICENSE ( "GPL" ) ;
MODULE_AUTHOR ( "Aleksander Alekseev" ) ;
MODULE_DESCRIPTION ( "A simple driver" ) ;

static char * name = "%username%" ;

module_param ( name , charp , 0 ) ;
MODULE_PARM_DESC ( name , "Enter your name" ) ;

static int __init init ( void ) <
pr_info ( "Hello, %s \n " , name ) ;
return 0 ;
>

static void __exit cleanup ( void ) <
pr_info ( "Goodbye, %s \n " , name ) ;
>

module_init ( init ) ;
module_exit ( cleanup ) ;

Из этого примера мы узнаем ряд важных вещей. Во-первых, что процедуры, вызываемые при загрузке и выгрузке модуля, могут называться как угодно. Во-вторых, что в модуле можно указать не только его лицензию, но также автора и краткое описание. Сравните вывод modinfo для этого модуля и предыдущего. И в-третьих, модуль может принимать параметры:

В логах мы предсказуемо увидим:

Параметры, переданные модулю, видны через sysfs. Но чтобы это работало, код нужно немного изменить:

Если теперь пересобрать модуль, то можно сделать так:

Думаю, что для первого раза удивительных открытий достаточно. Полная версия кода доступна в этом репозитории на GitHub. Там же есть список дополнительных материалов для самостоятельного изучения.

Я пытаюсь сделать свою собственную ОС, и мне нужна помощь с моим кодом. Это мой загрузчика.asm:

я компилирую его с этим:

это ядра.c:

я компилирую его с этим:

Я хочу знать, что я делаю неправильно, потому что, когда я тест с в QEMU он не работает. Может кто-нибудь дать несколько советов улучшение kernel.c поэтому мне не нужно использовать функцию call_main ()?

при тестировании я использую:

Мои Другие Файлы

a20.inc:

gdt.inc:

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

исходный код в вашем вопросе не установил SS регистр сегмента стека. Совет №1 я даю:

когда BIOS переходит на ваш код, вы не можете полагаться на CS, DS, ES, SS, SP регистры, имеющие допустимые или ожидаемые значения. Они должны быть настроены соответствующим образом при запуске загрузчика.

Если вам нужно ES он также должен быть установлен. Хотя в вашем коде это не так (за исключением функции print_string, которую я рассмотрю позже).

самая большая ошибка, которая помешала бы вам далеко уйти в защищенный режим, заключалась в том, что вы настроили глобальная таблица дескрипторов (GDT) в gdt.inc начиная с:

каждый глобальный дескриптор должен быть 8 байт, но dd 0 определяет только 4 байта (двойное слово). Должно быть:

это на самом деле кажется, что второй dd 0 был случайно добавлен в конец комментария к предыдущей строке.

вы написали какую-то print_string код, но он 32-битный код:

вы называете print_string как обработчик ошибок в 16-битном коде, поэтому то, что вы здесь делаете, скорее всего, приведет к перезагрузке компьютера. Нельзя использовать 32-разрядные регистры и адресацию. Код может быть 16-битным с некоторыми корректировками:

основное отличие (в 16-битном коде) заключается в том, что мы больше не используем EAX и EDX 32-битные регистры. Для доступа к видеопамяти @ 0xb8000 нам нужно использовать пару segment: offset, которая представляет то же самое. 0xb8000 может быть представлен как сегмент: offset 0xb800:от 0x0 (вычисляется как (0xb8000xb8000 физический адрес. Мы можем использовать эти знания для хранения b800 на ES регистрация и использование DI регистрация в качестве смещения для обновления видеопамяти. Теперь мы используем:

переместить слово в видеопамять.

одна из проблем при построении ядра заключается в том, что вы неправильно генерируете плоский двоичный образ, который можно загрузить в память напрямую. А не с помощью gcc -ffreestanding -o kernel.bin kernel.c я рекомендую сделать это таким образом:

это собирает ядра.c to ядра.o с отладочной информации ( -g ). Затем компоновщик принимает ядра.o (32-бит эльф binary) и производит эльф исполняемый файл называется ядра.эльф (этот файл будет удобен, если вы хотите отладить свое ядро). Затем мы используем objcopy взять исполняемый файл ELF32 ядра.эльф и преобразовать его в плоское бинарное изображение ядра.бин который может быть загружен BIOS. Ключевая вещь, чтобы отметить, что с -Tlinker.ld вариант мы просим LD(компоновщик) для чтения параметров из файл линкер.ld . Это просто linker.ld вы можете использовать, чтобы начать работу:

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

я рекомендую делать что-то подобное при использовании NASM так вместо того, чтобы делать nasm -f bin -o boot.bin bootloader.asm сделать это так:

это похоже на компиляцию C ядра. Мы не используем сценарий компоновщика здесь, но мы говорим компоновщику создать наш код, предполагая, что код (загрузчик) будет загружен в 0x7c00 .

для этого, чтобы работать вам нужно будет удалить эта строка из загрузчика.asm :

изменить ядра.c для:

на загрузчика.asm мы должны позвонить main функция (которая будет размещена на 0x9000), а не прыгать на нее. Вместо:

код после вызова будет выполняться, когда C функция main возвращается. Это простой цикл, который эффективно остановит процессор и останется таким до бесконечности, так как нам некуда возвращаться.

загрузчика.asm:

gdt.inc:

a20.inc:

ядра.c:

линкер.ld

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

вы можете создать образ диска (в этом случае мы сделаем его размером с дискету) с помощью следующих команд:

это создает образ диска с нулевым заполнением размером 512 * 2880 байт (размер дискеты 1,44 мегабайта). dd if=boot.bin of=disk.img bs=512 conv=notrunc пишет boot.бин в первый сектор файла без усечения образ диска. dd if=kernel.bin of=disk.img bs=512 seek=1 conv=notrunc мест ядра.бин в образ диска начиная со второй сектор. The seek=1 пропускает первый блок (bs=512) перед записью.

если вы хотите запустить ядро, вы можете запустить его как дисковод a: ( -fda ) в в QEMU такой:

вы также можете отлаживать 32-разрядное ядро с помощью в QEMU и отладчик GNU (GDB) с отладочной информацией, которую мы создали при компиляции/сборке кода с приведенными выше инструкциями.


Иногда может потребоваться собрать своё собственное ядро Linux. Причины для этого могут быть следующими:

  • вам нужно чистое ядро, без дистрибутивных патчей;
  • вы хотите наложить собственные патчи (коих очень много);
  • вы хотите собрать ядро под свою конфигурацию железа, выкинуть из него лишнее и/или заточить под определённые задачи;
  • вы хотите включить в состав ядра эксперементальный драйвер или файловую систему, которой нет в "ванильном" ядре (например ZFS или Raiser 4);
  • вам нужно будет пересобирать ядро при каждом его обновлении (качать "обновляющий патч", накладывать его и собирать ядро);
  • пересобранное ядро может не заработать, если в вашей системе используются какие-нибудь хаки для обеспечения работоспособности того или иного оборудования;
  • при неправильном конфигурировании ядра, особенно в случае неграмотного или бездумного наложения патчей, вы можете получить либо тормозящую до ужаса систему, либо лишиться её вовсе.

Простая сборка ядра без применения патчей.

Исходные коды ядра Linux находятся на сайте kernel.org. Там же находятся "обновляющие патчи". Что нам нужно? Качаем с сайта тарболл (архив) с последней стабильной версией ядра (на момент написания статьи, это версия 4.3). Качаем любым удобным способом. Далее нам потребуются инструменты для сборки:

sudo apt install build-essential gcc kernel-package patch
sudo apt-get build-dep linux

После того как установятся все необходимые инструменты, распакуйте архив с кодом ядра в любую удобную директорию. Пусть это будет /home/user/KERNEL, где "user" - имя пользователя системы. Далее откройте терминал и перейдите туда:

Осталось собрать ядро:

Цифра 3 после j - это количество ядер вашего процессора + 1. То есть для двухядерного это 3, для 4-х ядерного это 5 и так далее.
-custom - здесь можете указать удобное имя для ядра, чтобы было легче его отличить от дистрибутивного.
kernel_image и kernel_headers - это само ядро и его заголовочные файлы соответственно. Headers необходимы для сборки драйверов и модулей ядра, а также для некоторых других целей. После выполнения этой команды, начнут появляться несколько вопросов по конфигурированию ядра. Так как мы всё оставляем по умолчанию, просто жмите Enter пока не начнётся сборка. В зависимости от мощности вашего компьютера, сборка может занять от 15-20 минут до нескольких часов. После сборки, в директории /home/user появятся два deb-пакета: ядро и заголовки. Установите их командой:

sudo dpkg -i linux-image-4.3*deb linux-headers-4.3*deb
sudo update-grub

и перезагрузитесь. В меню GRUB теперь можно будет выбрать для загрузки системы другое ядро.

Сборка ядра с применением патчей и дополнительной конфигурации.

cd /home/user/KERNEL-CUSTOM
patch -p1 -i patch-4.1.13-rt15.patch --dry-run


Опция --dry-run позволяет симулировать применение патча, без внесения изменений в файлы. Если ошибок не обнаружено (см. скриншот) - примните патч уже без опции --dry-run. Аналогичные действия проведите и со вторым патчем. Не применяйте одновременно больше одного патча! Теперь нам нужно сконфигурировать наше ядро. На выбор нам предлагаются следующие варианты:

make config - в терминал будут поочерёдно выводиться вопросы о конфигурации той или иной подсистемы ядра. Крайне долгий и утомительный процесс. Забудем о нём :)
make oldconfig - будет задействована конфигурация работающего в данный момент ядра. Так как мы собираем своё с нуля, этот способ также бесполезен.
make defconfig - аналогично предыдущему, только значения будут по умолчанию. Такими, какими его задали разработчики ядра. Аналог первого способа сборки.
make menuconfig - псевдографический интерфейс на основе библиотеки Ncurses. На экран будет выводиться интерфейс с удобным иерархическим меню. Управления с помощью клавиш направления, пробела и клавиши TAB. Рекомендуется если вы собираете ядро в системе, не имеющей графической оболочки.
make gconfig - графический интерфейс на основе GTK, рекомендуется в окружениях GNOME, Mate, Xfce, Cinnamon, Unity и прочих, использующих GTK.
make xconfig - графический интерфейс на основе Qt. Рекомендуется в KDE. Так как в моей системе используется KDE, я воспользуюсь этим способом. Помимо этого есть ещё пара способов, но их применения ни чем особенным не отличается. Итак, после применения патчей, запускаем make xconfig и перед нами предстаёт вот это:


Первым делом выключаем dynticks. Для этого идём в Timers subsystem и выбираем Periodic timer ticks



Теперь самое вкусное. Идём в Processors type and features, ищем пункт Processor famaly и указываем вашу серию процессора. К примеру если у вас Intel Core i5-4xxx, указывайте Hasswell (4 поколение процессора). Если вы точно не уверены, то можете выбрать пункт Native optimizations autodetected by GCC. В этом случае, при сборке, компилятор сам определит что поддерживает ваш процессор, и включит все его фичи.


Идём ниже и включаем параметр Full preemptible kernel (RT). Режим жёсткого реального времени.


Листаем ниже и в пункте Timer frequency выставляем частоту системных прерываний на 1000 Гц


Полностью выключаем любое энергосбережение. Это важно! Слева ищем пункт Power management and ACPI options и снимаем галочку с ACPI. Также выключаем энергосбережение процессора


Вот и всё. При желании (и тщательном изучении документации), вы можете внести дополнительные изменения в конфигурацию (отключить лишние драйверы, задействовать дополнительные подсистемы и так далее). Теперь сохраняем конфиг через File - Save, закрываем конфигуратор и собираем ядро:

На моём компьютере с процессором Intel Core i3-550 (3.2 ГГц), прирост производительности был довольно ощутимый. Но самое главное - при работе в LMMS и Kdenlive, исчезли периодические заикания рассинхронизация звуковой и видеодорожек, а также подвисания при сильной нагрузке на жёсткий диск. Вывод - работает! Напоследок опишу два модифицированных ядра, которые весьма популярны в кругах линуксоидов:

PF-kernel - самый популярный набор патчей от украинца Александра Наталенко (aka post-factum). Это набор патчей, которые не входят в основное ядро, но обеспечивают повышенную отзывчивость системы, предоставляют альтернативную подсистему гибернации, более быструю, нежели основная, а также уменьшают использование памяти с помощью техники объединения одинаковых страниц. В набор входят:

  • планировщик процессов BFS от Кона Коливаса (Con Kolivas) с дополнительными исправлениями от Альфреда Чена (Alfred Chen);
  • планировщик ввода-вывода BFQ от Паоло Валенте (Paolo Valente), Арианны Аванзини (Arianna Avanzini) и Мауро Маринони (Mauro Marinoni);
  • подсистема гибернации TuxOnIce от Найджела Каннингема (Nigel Cunningham);
  • реализация техники слияния одинаковых страниц в памяти UKSM от Най Ся (Nai Xia);
  • патч от Graysky, расширяющий список процессоров для оптимизации ядра компилятором (тот, что мы применили выше)

Zen-kernel - второй по популярности, но первый по количеству патчей набор. Zen Kernel использует комбинацию нескольких проектов, обновляет код через git-репозиторий, а также имеет несколько специфичных для Zen вещей, стремящихся удовлетворить большинство потребностей пользователей, реализовав их в одном ядре. Некоторые возможности патча: drm-next, wireless-testing, выбор планировщиков CPU (CFS/BFS), BFQ-планировщик ввода-вывода, aufs, unionfs, reiser4, tuxonice, PHC и многие другие вещи, которые замечательно подойдут для оптимизации настольных систем или ноутбуков. Всё это доступно в виде одного патча к ванильному ядру. Официальный сайт. GIT- репозиторий. Пакеты для Debian/Ubuntu.

На сегодня, пожалуй, всё. Больше информации вы можете найти в ссылках к статье. Всё описанное в статье проверено мной на многих конфигурациях.


Интересуюсь по большей части системным анализом программного обеспечения: поиском багов и анализом неисправностей, а также системным программированием (и не оставляю надежд запилить свою операционку, хотя нехватка времени сказывается :) ). Программированием увлекаюсь с 12 лет, но так уж получилось, что стал я инженером.

Основная сфера моей деятельности связана с поддержкой Solaris и оборудования Sun/Oracle, хотя в последнее время к ним прибавились технологии виртуализации (линейка Citrix Xen) и всякое разное от IBM - от xSeries до Power. Учусь на кафедре Вычислительной Техники НИУ ИТМО.





Таумкрафт 6 - ураа!
Пишу на Scala
Какая ирония: написание тутора позволяет понять тему лучше, чем его чтение
Test BB-code

Icosider

iMixin

Возьми за основу обычное ядро майна, а если нужно моды использовать то forge, если хочешь ещё и плагины то бери ведро или кран. И ещё такой момент, термос параша, тот же KCauldron лучше будет.
"в качестве исходного материала ядро thermos, которое недавно перестали разрабатывать." - даже не удивлён, что его перестали разрабатывать.

hohserg




Они сначала написали, что просто не разрабатывают, потом еще и дополнили: "не решаем issues, просто закрываем"
---
Мне хочется стартовать от термоса, т.к. он хорошо себя показал за год работы сервера. В чем он и параша: иногда случаются краши, почти все связаны с ConcurrentModificationException, но после рестарта все норм
---
Спасибо, попробую начать от forge, но как к нему прикрутить bukkit?


Таумкрафт 6 - ураа!
Пишу на Scala
Какая ирония: написание тутора позволяет понять тему лучше, чем его чтение
Test BB-code

Liahim

Народ, вы все тут конечно мегапрограммисты. Объясните плиз, что значит разработка ядра?
Типа майн с нуля написать?

Maxik

Голубой Петушок

Типо написать сервер. Который будет майн запускать.

Майн с нуля если, тогда лучше не на яве писать
Если ты в курсе, майн написан на яве не от желания. Потому что это изначально планировалась браузерная игра.

Делаю воксельные(и не только) 3D-модели для ваших Minecraft проектов. Портфолио можете увидеть полистав группу моего мода Soviet Lab - все модели сделаны мной.

Icosider

iMixin

Типо написать сервер. Который будет майн запускать.

Майн с нуля если, тогда лучше не на яве писать
Если ты в курсе, майн написан на яве не от желания. Потому что это изначально планировалась браузерная игра.

Maxik

Голубой Петушок

Да ты чего. Поищи повнимательнее. Первая CaveGame запускалась в браузере, чувак.

Совсем первая. Прям вообще. Там никаких блоков не было, ничего. Тупо статичная карта, по которой можно побегать и все.
И она даже помойму не так называлась.

Делаю воксельные(и не только) 3D-модели для ваших Minecraft проектов. Портфолио можете увидеть полистав группу моего мода Soviet Lab - все модели сделаны мной.

Icosider

iMixin

Они сначала написали, что просто не разрабатывают, потом еще и дополнили: "не решаем issues, просто закрываем"
---
Мне хочется стартовать от термоса, т.к. он хорошо себя показал за год работы сервера. В чем он и параша: иногда случаются краши, почти все связаны с ConcurrentModificationException, но после рестарта все норм
---
Спасибо, попробую начать от forge, но как к нему прикрутить bukkit?

Декомпильне bukkit ядро(если нет исходников) и смотри реализацию. Ведро ж написано с использованием обычного mc сервера, просто оно дополняет его, как тот же самый forge для mc.

Да ты чего. Поищи повнимательнее. Первая CaveGame запускалась в браузере, чувак.

Совсем первая. Прям вообще. Там никаких блоков не было, ничего. Тупо статичная карта, по которой можно побегать и все.


CaveGame и Minecraft это две разные игры, и то что когда-то там в далёком 2010-2011 годах её запускали в браузере, это не значит что её писали для веба. Да и все браузерные игры шлак в основе которых лежит донат.

hohserg




"Ведро ж написано с использованием обычного mc сервера, просто оно дополняет его, как тот же самый forge для mc." Мм, делать то, что уже кто-то сделал.

Народ, вы все тут конечно мегапрограммисты. Объясните плиз, что значит разработка ядра?
Типа майн с нуля написать?


Таумкрафт 6 - ураа!
Пишу на Scala
Какая ирония: написание тутора позволяет понять тему лучше, чем его чтение
Test BB-code

Icosider

iMixin

"Ведро ж написано с использованием обычного mc сервера, просто оно дополняет его, как тот же самый forge для mc." Мм, делать то, что уже кто-то сделал.

Maxik

Голубой Петушок

CaveGame и Minecraft это две разные игры, и то что когда-то там в далёком 2010-2011 годах её запускали в браузере, это не значит что её писали для веба. Да и все браузерные игры шлак в основе которых лежит донат.


и всеже CaveGame это прародитель майна

Делаю воксельные(и не только) 3D-модели для ваших Minecraft проектов. Портфолио можете увидеть полистав группу моего мода Soviet Lab - все модели сделаны мной.

Credence

Возьми за основу обычное ядро майна, а если нужно моды использовать то forge, если хочешь ещё и плагины то бери ведро или кран. И ещё такой момент, термос параша, тот же KCauldron лучше будет.
"в качестве исходного материала ядро thermos, которое недавно перестали разрабатывать." - даже не удивлён, что его перестали разрабатывать.


А есть какие-то пруфы того, что утверждаешь в такой агрессивной форме? С какого это чёрта Thermos хуже?

Icosider

iMixin

Возьми за основу обычное ядро майна, а если нужно моды использовать то forge, если хочешь ещё и плагины то бери ведро или кран. И ещё такой момент, термос параша, тот же KCauldron лучше будет.
"в качестве исходного материала ядро thermos, которое недавно перестали разрабатывать." - даже не удивлён, что его перестали разрабатывать.


А есть какие-то пруфы того, что утверждаешь в такой агрессивной форме? С какого это чёрта Thermos хуже?

А вот и фанбой прибежал защищать говно. Ответ на твой вопрос дал сам ТС " В чем он и параша: иногда случаются краши, почти все связаны с ConcurrentModificationException, но после рестарта все норм". Так же в нём дожую ошибок и само по себе ядро не стабильное.

Credence

Возьми за основу обычное ядро майна, а если нужно моды использовать то forge, если хочешь ещё и плагины то бери ведро или кран. И ещё такой момент, термос параша, тот же KCauldron лучше будет.
"в качестве исходного материала ядро thermos, которое недавно перестали разрабатывать." - даже не удивлён, что его перестали разрабатывать.


А есть какие-то пруфы того, что утверждаешь в такой агрессивной форме? С какого это чёрта Thermos хуже?

А вот и фанбой прибежал защищать говно. Ответ на твой вопрос дал сам ТС " В чем он и параша: иногда случаются краши, почти все связаны с ConcurrentModificationException, но после рестарта все норм". Так же в нём дожую ошибок и само по себе ядро не стабильное.

Глупый ты человек, вот серьёзно, резкие высказывания не делают из тебя в глазах других людей крутого или же всезнающего, а лишь доказывают твою незрелость, запомни это. По поводу Thermos - не замечал такой ошибки в нём, а сами разработчики в первую очередь преследовали цель фикса некоторых багов с модами, с чем отлично справлялись, до того как поняли что это неблагодарная работа. А конкретики на мой вопрос почти никакой не было, лишь резкие высказывания и сливы.

Icosider

iMixin

Глупый ты человек, вот серьёзно, резкие высказывания не делают из тебя в глазах других людей крутого или же всезнающего, а лишь доказывают твою незрелость, запомни это. По поводу Thermos - не замечал такой ошибки в нём, а сами разработчики в первую очередь преследовали цель фикса некоторых багов с модами, с чем отлично справлялись, до того как поняли что это неблагодарная работа. А конкретики на мой вопрос почти никакой не было, лишь резкие высказывания и сливы.

У меня Sponge и мне пофиг на термос. "с чем отлично справлялись, до того как поняли что это неблагодарная работа" - почему тогда spigot, sponge, forge всё ещё живут? И если у тебя ошибок нет, это не значит, что их вообще нет.

Dahaka

Если ты в курсе, майн написан на яве не от желания. Потому что это изначально планировалась браузерная игра.


Сейчас бы браузерные игры на java писать.

Термос это же просто отдельная ветка котла. И появилась точно так же - просто не хотели фиксить баги, кто-то пофиксил и залил.

hohserg




Попробовал собрать KCauldron - та же ошибка

Кажется, недоступны некоторые источники для библиотек
И лог не совсем такой же:

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug
option to get more log output.

Читайте также: