Comments 19
Смотрю, работа над форком ядра, которое тут недавно предлагали, продвигается успешно!)))
Спасибо, думаю материал будет полезен некоторой категории. Попробуйте такое же проделать с каким нибудь seL4 мicrokernel(ссылку не кидаю на проект так как минуса накидали за рекламу) и в идеале на risc-v, было бы интересно почитать. Конечно при условии что у вас найдется время.
Спасибо за наводку. Тут так получается - пока с одной статьёй сам разобрался, новых вопросов и новых мыслей народилось - и правда вроде для следующей статьи :)
А что про RISC-V имеется в виду? портирование ядер для них или там какую-то отдельную ОС уже мутят? :) вряд ли. Вообще про порты тоже оказывается любопытно, как они интерфейс системных вызовов перелопачивают, уф. Посмотрим, разберемся.
Думаю достаточно собрать (risc-v опционно, можно под любую платформу) и запустить с сетевым драйвером (остальное не надо - в том числе видеодрайвер) и user space процесс. Базовая функция user process: запрос сетевой в виде /world и получить ответ в виде например "hello world". Да задача не простая, но с практической стороны намного будет полезно читателям.
Спасибо за статью.
Linux и FreeBSD под RISC-V давно и прочно существуют. Системные вызовы те же и от платформы не зависят. Визуально они ни чем не отличаются.
По теме статьи. Интересным является то, как продвинуться чуть дальше запуска статически слинкованного /sbin/init. А именно - как организуется динамическая линковка, организация библиотек и что такое GLIBC. Именно с этого момента начинается настоящая операционная система, а до этого - только загрузка ядра как обычной программы. :)
В качестве продолжения, было бы интересно посмотреть как запустить Xorg + Firefox (в режиме киоска например) на минималках. Firefox интересен тем, что имеет минимум зависимостей, только системные библиотеки:
rz@butterfly:~ % ldd /usr/local/bin/firefox
/usr/local/bin/firefox:
libc++.so.1 => /usr/lib/libc++.so.1 (0x151a43e38000)
libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x151a452a3000)
libm.so.5 => /lib/libm.so.5 (0x151a442a1000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x151a46377000)
libthr.so.3 => /lib/libthr.so.3 (0x151a4597e000)
libc.so.7 => /lib/libc.so.7 (0x151a46fe6000)
[vdso] (0x7ffffffff650)
Еще интересным моментом является ответ на вопрос "а что же на самом деле делает загрузчик ?". Процесс загрузки ядра Linux в память и его запуск - не тривиален.
Спасибо за вопросы-подсказки :) как нетрудно догадаться я сам не слишком глубоко в теме - так что конечно они вероятно дадут толчок к дополнительным размышлениям :)
Начинаем переизобретать LFS?
По-хорошему нужно взять исходники и вдумчиво скомпилировать ядро нужной версии и с требуемыми настройками
как то немного думалось что это будет в статье, хотя для понимания процесса это большой шаг в сторону, а в настройках там заблудиться можно, так что для данной статьи готовое ядро - правильный выбор
так то есть такие штуки как buildroot которые позволят и ядро собрать и initrd и файловую систему в образе, ну еще openwrt недалеко ушла, но понятия того как все грузится такая сборка не особо разовьет
Например можно утащить
initrd
файл с Убунты (он весит около 50мб) - и попробовать подключить его. Вы получите уже более менее рабочую систему - однако убедитесь что надо создать на диске кое-какие папки (вроде/dev
) да и подмонтировать его как рутовую систему.
Можно просто взять busybox - его вполне достаточно для многих вещей (пример сборки rootfs из одного busybox https://github.com/maquefel/kernel-bisect-template/blob/master/Makefile) получится меньше двух мегабайт (может даже сильно меньше - не помню).
Можно, так же, объединить с ядром - CONFIG_INITRAMFS_SOURCE, причём мы можем не использовать его добавил параметр:
noinitrd [RAM] Tells the kernel not to load any configured initial RAM disk.
или загрузить другой невстроенный.
Можно просто взять busybox
собственно он и используется в упомянутом initrd c убунты :) действительно популярная штуковина
noinitrd
у меня сложилось впечатление что не работает (на ядрах из примера), но я, каюсь, не разобрался - то ли надо вдумчиво остальные параметры задать, то ли ядро без поддержки этого параметра %)
собственно он и используется в упомянутом initrd c убунты :) действительно популярная штуковина
Его можно использовать ВМЕСТО initrd c убунты, как бы 50 vs 2 это большая разница (уже не говоря о скорости systemd vs упрощенная версия sysvinit в busybox).
у меня сложилось впечатление что не работает (на ядрах из примера),
Тут ничего сказать не могу, кроме того, что обычно оно работает.
А вот rdinit= vs init=, надо было бы упомянуть.
initrd — это Initialization RAM Disk. А не “init root directory”.
Вообще, более современный вариант будет — собрать ядро с включенным efi stub, положить его в /efi/bootx64.efi внутри fat32/gpt раздела. И тогда загрузчик не нужен вообще. Можно вкомпилировать аргументы запуска в ядро. Можно запустить ядро из uefi shell. Ну и морочиться с копированием файлов в виртуалку не нужно. Просто собираем образ диска в хост-системе и подключаем его к виртуалке в качестве usb устройства или sata диска.
Просто собираем образ диска в хост-системе
ну дак это у кого какая хост-система :) линуксоводам (как и мне) и виртуалка не нужна
и как сказано в статье - я колебался между желанием добавить этап сборки ядра и тягой к тому чтобы keep it simple. пока решил за второй вариант хотя безусловно он не очень правильный
Замечания по статье и комментариям:
initramfs -- по сути вполне себе userspace, а не "ядро-одиночка", "ядро само по себе" и т.д.
Чтоб запустить в виртуалке ядро с initramfs, не нужно никаких образов дисков, форматирований, загрузчиков и проч. Для
qemu
есть опции запуска конкретного ядра и initramfs, взятых файлами из хостовой ОС. Как там в гуеподелке и виртуальной коробке -- не в курсе.
Была мысль попробовать собрать ядро как EFI-приложение, и в него вкомпилить busybox с тем же докером. Подписать это дело. И у нас получится система в одном файле... Зачем? Ну, как минимум, такая штука имеет мало векторов для атаки и создает сложность закрепления в ней.
Примерно такая же схема была раньше в роутерах - все работало из оперативки, но там не один файл таки, а целый набор разделов.
Голый Линукс — запуск ядра-одиночки