Вопрос или проблема
Я работаю над встроенным Linux (ядро-5.10.24) и включил early_printk в конфигурации ядра, чтобы помочь в отладке ядра.
Обычно командная строка ядра установлена как console=ttyS0,115200 ....
, и я вижу логи early printk в ядре.
Но сегодня я по ошибке изменил командную строку на console=ttyS1,115200 ....
и предполагал, что не увижу никаких логов ядра во время загрузки ядра.
К моему удивлению, я все еще вижу первую часть лога ядра, выполненную с помощью early printk, после этого НЕТ других логов.
Так что мой вопрос: как early printk выводит логи ядра на правильный
консоль, даже если console=
установлена на несуществующее устройство (или неправильный последовательный консоль) ?
Учитывая значение, указанное в параметре загрузки консоли, я предполагаю, что ваш терминал подключен к системе через некоторую последовательную линию.
как early printk выводит логи ядра на правильный консоль, даже если
console= установлена на несуществующее устройство
Причина этого проста: сообщения терминала на ранней стадии загрузки будут выводиться на некоторый терминал независимо от значения параметра загрузки console, а определятся вместо этого параметром earlyprintk.
Параметр загрузки console только определяет “реальную” консоль. т.е. терминал, который будет использоваться в качестве консоли, когда стандартные драйверы linux будут правильно инициализированы, это будет происходить около начала фазы инициализации.
Если вы неправильно установите этот параметр, логически, ничего не будет выводиться на системную консоль после времени загрузки.
Какова настройка консоли для раннего вывода ядра early_printk в Linux?
Как вы можете прочитать из Параметров командной строки ядра:
earlyprintk=vga
earlyprintk=sclp
earlyprintk=xen
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=serial[,0x…[,baudrate]]
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
earlyprintk=pciserial[,force],bus:device.function[,baudrate]
earlyprintk=xdbc[xhciController#]earlyprintk полезен, когда ядро падает до того, как нормальная консоль инициализирована. По умолчанию он не включен, потому что имеет некоторые косметические проблемы.
Добавьте “,keep”, чтобы не отключать его, когда реальная консоль начинает работать.
Только один из vga, efi, serial или usb debug port может использоваться одновременно.
В настоящее время только ttyS0 и ttyS1 могут быть указаны по имени. Другие порты ввода-вывода могут быть явно указаны на некоторых архитектурах (по меньшей мере x86 и arm), заменив ttySn на адрес порта ввода-вывода, например: earlyprintk=serial,0x1008,115200 Вы можете найти порт для данного устройства в /proc/tty/driver/serial: 2: uart:ST16650V2 port:00001008 irq:18 …
Взаимодействие со стандартным последовательным драйвером не очень хорошее.
Вывод VGA и EFI в конечном итоге затеряется реальной консолью.
Вывод xen может использоваться только гостями Xen PV.
Вывод sclp может использоваться только на s390.
Опциональный “force” для “pciserial” позволяет использовать устройство PCI, даже когда его classcode не принадлежит классу UART.
Ответ или решение
Консольные настройки для вывода журнала ядра через early_printk в Linux
Ваша ситуация с использованием early_printk в Embedded Linux (ядро версии 5.10.24) довольно интересна и представляет собой важный аспект отладки встраиваемых систем. Давайте подробно разберем, как работает early_printk и почему вы все еще видите сообщения журнала, несмотря на неверную настройку параметра console=
.
По умолчанию параметр console=
определяет реальную консоль, на которую будут выводиться сообщения журнала после инициализации стандартных драйверов. Ваша ошибка, связанная с изменением console=ttyS0
на console=ttyS1
, должна была, казалось бы, привести к отсутствию сообщений вывода после стадии инициализации ядра. Однако early_printk работает независимо от этого параметра.
Как работает early_printk
early_printk — это механизм, который позволяет ядру выводить сообщения логирования очень рано в процессе загрузки, даже до того, как будет инициализирована фактическая консоль, указанная в параметре console=
. Он используется в основном для отладки, особенно в случаях, когда система может зависнуть или упасть еще до полной инициализации всей аппаратуры и драйверов.
Настройки early_printk:
Как указано в документации к ядру, параметры, которые вы можете использовать для конфигурации early_printk, включают:
- earlyprintk=vga – для вывода на VGA.
- earlyprintk=sclp – для больших систем s390.
- earlyprintk=xen – для виртуальных машин Xen.
- earlyprintk=serial[,ttySn[,baudrate]] – для настройки串行ного порта (например,
serial,ttyS0,115200
). - earlyprintk=serial[,0x…[,baudrate]] – для явной установки адреса I/O порта.
- earlyprintk=ttySn[,baudrate] – другой способ указания tty.
- earlyprintk=dbgp[debugController#] и другие.
Почему вы видите сообщения
Вы все еще наблюдаете вывод early_printk, потому что:
- early_printk использует свои собственные механизм для отправки сообщений, что позволяет ему работать независимо от стандартной конфигурации консоли. Он может выводить данные напрямую на терминал или через другой интерфейс, даже если основной параметр консоли настроен неверно.
- Параметр
earlyprintk
не привязан к правильно настроенномуconsole=
; он работает на более ранних этапах загрузки, когда система ещё не завершила инициализацию всех необходимых компонентов.
Рекомендации
Если вы хотите продолжать использовать early_printk:
- Убедитесь, что параметр
earlyprintk
настроен правильно в командной строке ядра. - Вы можете использовать дополнительные параметры, такие как
,keep
, чтобы предотвратить отключение early_printk, когда реальная консоль захватывает управление.
Эти аспекты помогут вам лучше управлять выводом сообщений и отладкой в процессе загрузки вашего встраиваемого Linux.