Подробный гайд: ncurses и кастомное ядро Linux

Ncurses не работает в ядре: это user-space библиотека. Для запуска нужны CONFIG_VT, CONFIG_TTY и rootfs с libc, libtinfo, terminfo. Собирайте кросс-тулчейном.

2026.04.24                  


Подробный гайд: `ncurses` и кастомное ядро LinuxПодробный гайд: `ncurses` и кастомное ядро Linux Прежде чем углубляться в технические детали, важно сразу прояснить фундаментальный архитектурный момент, который часто вызывает путаницу:

ncurses

  • это пользовательская (user-space) библиотека. Ядро Linux работает в kernel space и не может линковаться ни с libncurses, ни с glibc, ни с любой другой стандартной библиотекой пользовательского пространства.

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


Сценарий 1: Вы хотите текстовый/консольный интерфейс внутри самого ядра

Почему ncurses не подойдёт

  • Ядро не имеет динамического линкера (ld.so)
  • Отсутствует stdio, malloc, signal, termios в привычном виде
  • Терминал управляется через подсистемы tty, vt, console, а не через ANSI-эскейп последовательности в пользовательском стиле
  • Компилятор выдаст ошибки на #include <ncurses.h> ещё на этапе сборки ядра

Что использовать вместо ncurses в ядре

Задача Встроенный механизм ядра
Вывод текста в консоль printk(), console->write(), vc_scrolldelta
Интерактивный ввод в консоли tty_input(), kbd_event(), input subsystem
Псевдографика/курсор con_write(), update_screen(), fbcon / drm
Отладочные интерфейсы debugfs, sysfs, procfs, seq_file
Простое меню в консоли Самописный обработчик на основе tty + ANSI-последовательности (ограниченно)

Обязательные опции ядра для полноценной работы консоли

Если вы собираете кастомное ядро и хотите, чтобы в user-space корректно работали терминалы (включая ncurses-приложения), убедитесь, что включены:
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_HW_CONSOLE=y
CONFIG_LEGACY_PTYS=y          # если нужны /dev/pty*
CONFIG_SERIAL_8250_CONSOLE=y  # для serial-консоли
CONFIG_FB=y или CONFIG_DRM_FBDEV_EMULATION=y  # для framebuffer
CONFIG_TTY=y
CONFIG_UNIX98_PTYS=y

Эти опции не добавляют ncurses в ядро, а обеспечивают корректную работу /dev/tty* и терминальных драйверов, от которых зависят пользовательские приложения.


Сценарий 2: Вы запускаете ncurses-приложения поверх кастомного ядра

Это штатный сценарий. Ядро само по себе не требует библиотек для ncurses. Всё зависит от вашего rootfs / toolchain / user-space окружения.

Зависимости ncurses (компиляция и запуск)

Тип Зависимость Примечание
Compile-time gcc / clang, make, pkg-config, bash Стандартный тулчейн
Compile-time Заголовки libc (stdio.h, unistd.h, termios.h, dlfcn.h) Обычно в sysroot
Run-time libc.so (glibc / musl / uClibc) Динамический линкер + базовая libc
Run-time libtinfo.so (или libncurses.so с встроенным termlib) Современный ncurses разделён на libncurses + libtinfo
Run-time terminfo база (/usr/share/terminfo) Без неё ncurses не сможет рисовать интерфейсы
Run-time /dev/tty*, /dev/ptmx Предоставляются ядром + devtmpfs / udev

Пошаговая сборка ncurses под кастомную систему

1. Подготовка тулчейна

Если вы собираете rootfs с нуля, используйте один из подходов:

  • Buildroot: make menuconfigTarget packages → Libraries → ncurses (всё настроится автоматически)
  • Yocto/OpenEmbedded: IMAGE_INSTALL += "ncurses terminfo"
- Вручную (кросс-компиляция):
  export CROSS_COMPILE=arm-linux-gnueabihf-
  export SYSROOT=/path/to/your/sysroot

  ./configure \
    --host=arm-linux-gnueabihf \
    --prefix=/usr \
    --with-shared \
    --with-termlib \
    --without-debug \
    --without-ada \
    --enable-widec \
    --with-default-terminfo-dir=/usr/share/terminfo

  make -j$(nproc)
  make install DESTDIR=$SYSROOT

2. Проверка зависимостей собранной библиотеки

$ file $SYSROOT/usr/lib/libncurses.so.6
$ ldd $SYSROOT/usr/lib/libncurses.so.6
  linux-vdso.so.1 => (0x...)
  libtinfo.so.6 => /usr/lib/libtinfo.so.6
  libc.so.6 => /lib/libc.so.6
  /lib/ld-linux-armhf.so.3 => /lib/ld-linux-armhf.so.3

Убедитесь, что все пути указывают на корректный sysroot или rootfs.


3. Копирование terminfo

База терминов обязательна.

Без неё initscr() вернёт NULL или будет использовать сырой режим:

cp -r /usr/share/terminfo $SYSROOT/usr/share/

4. Тестовое приложение

// test_ncurses.c
#include <ncurses.h>
int main() {
    initscr();
    printw("Hello from custom kernel space!\n");
    refresh();
    getch();
    endwin();
    return 0;
}

Сборка:

$CC test_ncurses.c -o test_ncurses -lncurses -ltinfo

Копирование в rootfs + проверка:

$ ldd test_ncurses
$ chroot $SYSROOT /usr/bin/test_ncurses

Чек-лист готовности системы к ncurses

Компонент Статус Как проверить
Ядро: CONFIG_VT=y, CONFIG_TTY=y OK/FAIL zcat /proc/config.gz | grep -E 'VT|TTY'
Динамический линкер в rootfs OK/FAIL ls /lib/ld-*.so*
libc + libtinfo + libncurses OK/FAIL ldd /usr/bin/ncurses_app
База terminfo OK/FAIL ls /usr/share/terminfo/x/xterm
/dev/tty*, /dev/ptmx доступны OK/FAIL ls -l /dev/tty* /dev/ptmx
Переменная TERM установлена OK/FAIL echo $TERM (обычно xterm-256color или linux)

Альтернативы и рекомендации

Задача Рекомендуемое решение
Лёгкий текстовый UI в embedded newt, slang, или прямой вывод через termios + ANSI
Консольное меню в initramfs busybox ash + dialog/whiptail (собраны статически)
Графический framebuffer UI fbterm, psplash, directfb или SDL2 с fbdev
Минимальный rootfs для ncurses musl + ncurses (static) + busybox → ~2-4 МБ

Важно:

  • Если вы собираете ядро для embedded/IoT и хотите сэкономить место, рассмотрите статическую сборку ncurses с флагом --with-shared=no. Это увеличит размер бинарника, но уберёт зависимость от .so в runtime.

Итог

  1. ncurses не линкуется с ядром и не может использоваться внутри kernel space.
  2. Для работы ncurses-приложений кастомному ядру нужны только стандартные подсистемы терминала (CONFIG_VT, CONFIG_TTY, CONFIG_FB/DRM).
  3. Все библиотеки (libc, libtinfo, libncurses, terminfo) собираются и разворачиваются в user-space rootfs.
  4. При кросс-компиляции обязательно указывайте --host, --prefix, --with-termlib и копируйте terminfo.
  5. Используйте Buildroot/Yocto для автоматизации, если собираете систему с нуля.