Как диагностировать и отладить зависание платы на RK3568 в U-Boot на этапе вывода сообщения "Starting kernel"?

Добрый день. Пытаюсь собрать систему для Inmys SOM на RK3568 с поддержкой загрузки с разных разделов через extlinux.conf. Разделы созданы и файлы размещены, но проблема не в этом: при загрузке ОС процесс останавливается даже если просто загрузить в память образ ядра и DTB — зависает на "Starting kernel…". Как можно отладить этот этап загрузки? Ядро версии 6.6. Отладка в ядре включена.
  • 16 апреля 2026 г. 15:05
Ответы на вопрос 1
Ниже — набор практических шагов и приёмов, которые обычно помогают локализовать и исправить зависание на этапе «Starting kernel…» при загрузке RK3568 из U‑Boot. Пишите по шагам, пробуйте и возвращайтесь с результатами — дам дальнейшие рекомендации.

1) Убедитесь, что вы действительно прыгаете в правильный образ (Image / тип команды)
- Для aarch64 в U‑Boot обычно нужно загружать несжатый linux Image и использовать команду booti:
  - Пример:   
    setenv fdt_addr_r 0x46000000  
    setenv kernel_addr_r 0x42000000  
    booti ${kernel_addr_r} - ${fdt_addr_r}
- Если у вас zImage / Image.gz — используйте соответствующую команду (bootz), но для arm64 стандартом является Image+booti. Ошибочный тип загрузки может привести к немедленному зависанию.

2) Проверьте, что DTB правильный и передан корректно
- В U‑Boot: fdt addr ${fdt_addr_r} ; fdt check || echo "DTB corrupted"
- Убедитесь, что DTB соответствует конкретной плате/Inmys SOM. Неправильный DTB может привести к тому, что контроллеры питания/клоки/порты будут настроены неверно и ядро «ушло в тихий WFI».
- Попробуйте загрузить тот же DTB/ядро, который поставляет продавец платы (если есть) — это быстрый тест на совместимость.

3) Уточните консоль (console) — самая частая причина «нет вывода»
- U‑Boot печатает «Starting kernel…», но ядро может писать в другой UART. Проверьте bootargs: printenv bootargs
- Приведите корректный console=... в bootargs, например:
  - setenv bootargs 'console=ttyS2,115200 root=/dev/ram0 rw rootwait loglevel=8'
- Для ранних сообщений (до драйверов) используйте earlycon:
  - Найдите физ. адрес UART в DTB (узел uart@...) и добавьте, например:
    earlycon=pl011,mmio,0xff180000
  - Или: earlycon=uart8250,mmio,0xff180000
- Если не знаете адреса UART — откройте DTS/DTB и найдите node uart@xxxxxx (reg).

4) Включите в ядре низкоуровневую отладку (если ещё не включили)
- CONFIG_EARLY_PRINTK / CONFIG_DEBUG_LL — при включении дают вывод до initramfs и большинства драйверов.
- Убедитесь, что драйвер UART, соответствующий раннему консоли, встроен в ядро (не модулем).

5) Попробуйте простую initramfs / root=/dev/ram0
- Сформируйте initramfs с /init, который сразу делает printk и sleep, чтобы понять, успешно ли ядро проходит init:
  - Используйте rdinit=/init или root=/dev/ram0
- Таким образом можно проверить, что проблема — в инициализации rootfs или в самом ядре на более ранней стадии.

6) Логирование/повышение уровня логов
- Добавьте в bootargs: loglevel=8 initcall_debug printk.time=1 panic=10
- initcall_debug помогает увидеть, если зависание происходит в ранних initcalls.

7) Нет вывода, но ядро запущено — альтернативные каналы
- Netconsole: если network stack и драйвер инициализируются достаточно рано, можно настроить netconsole=... в bootargs и ловить printk в сети. Это может помочь, когда UART не работает.
- Если нет вывода совсем — JTAG / аппаратный отладчик (J‑Link, OpenOCD). С помощью JTAG можно посмотреть, где «застрял» CPU (адрес PC), стек, регистры.

8) Проверка специфики Rockchip (питание/BL31/ATF)
- RK SoC обычно зависит от BL31 (ARM Trusted Firmware) и от правильных параметров в DTB (power domains, regulators). Если вы меняли BL31/ATF/firmware, убедитесь, что:
  - СBL31 корректен и совместим с вашим U‑Boot/ядром.
  - Не нарушено управление питанием/клоками.
- Если BL31 некорректен, U‑Boot мог запуститься, но ядро потом вызывает операции с power domains и «зависает».

9) Проверка образа/адресов загрузки
- Убедитесь, что kernel_addr_r и fdt_addr_r не пересекаются и загружаются в правильные места.
- В U‑Boot: md ${kernel_addr_r} 8 ; md ${fdt_addr_r} 20 — проверить содержание.

10) Диагностика «без вывода» — как быстро проверить, запустилось ли ядро
- Попробуйте загрузить простой тестовый образ, например upstream kernel build с minimal defconfig для rk3568 или vendor image, который точно работает на плате — это позволит отделить проблему ядра от конфигурации.
- Если upstream тоже «виснет», вероятность аппаратного/firmware/DTB вопроса выше.

11) Конкретные примеры команд в U‑Boot
- Пример последовательности:
  - setenv kernel_addr_r 0x42000000
  - setenv fdt_addr_r 0x46000000
  - setenv bootargs 'console=ttyS2,115200 earlycon=pl011,mmio,0xff180000 root=/dev/ram0 rw rootwait loglevel=8 initcall_debug'
  - booti ${kernel_addr_r} - ${fdt_addr_r}

12) Если всё ещё виснет — что собрать и прислать мне
- Вывод serial порта вплоть до «Starting kernel…»
- Содержимое bootargs и используемые адреса (kernel_addr_r, fdt_addr_r)
- Версия U‑Boot, команда загрузки (booti/bootz/bootm), тип образа (Image/zImage/fit)
- Фрагмент DTS (uart node, chosen/stdout-path)
- Конфигурация ядра (или минимум: включены ли CONFIG_EARLY_PRINTK/DEBUG_LL)
- Информация о BL31/ATF (версия/файлы) и схема загрузки вашей платы

Короткое итоговое руководство действий сейчас (порядок, который рекомендую выполнить немедленно):
1. Проверить и явным образом задать правильный console= и earlycon= в bootargs. Перезагрузить и смотреть serial.
2. Убедиться, что вы используете booti + Image + корректный DTB.
3. Пересобрать ядро с CONFIG_EARLY_PRINTK/CONFIG_DEBUG_LL и сделать earlycon совпадающим с адресом UART из DTS.
4. Если по serial по‑прежнему нет вывода — попробовать netconsole или JTAG.

Если пришлёте вывод serial (до и после «Starting kernel…»), ваш bootargs и строки U‑Boot (каким образом загружаете образы), помогу локализовать дальше и предложу, какие параметры ещё менять.
Похожие вопросы