LINUX.ORG.RU
ФорумMobile

fbcon и initramfs

 


1

2

Пилю kexec ядро для смарта. Делаю из вполне рабочего ядра. Без initramfs ядро стартует и ругается на отсутствие rootfs, что логично. Всё это можно лицезреть на экране. Врубаю туда initramfs (не initrd!). Ядро перестаёт отображать консоль, но перезагружает смарт по таймауту kernel panic. Что ему может быть надо? Мне нужно создать рамдиск с двумя бинарниками: init и kexec. BusyBox пихать не охота, т.к. размер ядра сильно ограничен.


Ты собираешь boot.img и заливаешь в соответствующий раздел или у тебя ядро на отдельном разделе?

Если boot.img, то возможно ошибка в смещении (base) или командной строке, которая передается ядру. Надо посмотреть на рабочий boot.img

tlx ★★★★★
()
Ответ на: комментарий от tlx

Spica - это один из самых первый смартов на ведре, поэтому там всё не как у других. Прошивается он zImage, упакованным в tar. Командная строка: «console=tty0», этого хватает, чтобы без initramfs ядро выводило лог на экран (хоть и паниковало)

Я думаю, что проблема в нодах устройств или initramfs просто на своём этапе блокирует fbcon.

WOLF
() автор топика
Ответ на: комментарий от WOLF

Подловил.

Ты наверное знаешь, что дуалбут можно организовать пожертвовав recovery. Рисковано, но вариант.

Я как-то раз вынимал из ядра код инициализации видеоадаптера SoC. Дай точную ссылку на исходники ядра, которое собираешь и свой config. Я посмотрю и другим будет проще.

Если указать в качестве init elf-файл в initramfs, который пишет что-нибудь в стандартный вывод и уходит в вечный цикл, то на экране тоже ни чего не появляется?

tlx ★★★★★
()
Последнее исправление: tlx (всего исправлений: 1)
Ответ на: комментарий от tlx

Конкретно в Спике нет отдельного ядра под recovery, она просто бинарник в initramfs основного ядра.

Ядро: https://github.com/LONELY-WOLF/spica-linux-3.0

Конфиг: http://pastebin.com/Kf2gNfZW

Бинарник такой есть, но продолжает висеть бутлого.

Ещё initramfs_list: http://pastebin.com/2xHzdak0 Права пока лень выставлять.

WOLF
() автор топика
Ответ на: комментарий от WOLF

посмотрю в понедельник.

Я вспомнил как собирал минимальный образ для работы adb. Можно подцепиться по usb и там уже разобраться с видео. Потом adb уберешь если не нужен. Ты так делал?

tlx ★★★★★
()
Ответ на: комментарий от tlx

Я предпочитаю вешать Gadget Serial на USB, а на него консоль. Но USB слишком поздно инициализируется, лог загрузки на нём не получишь без рабочей системы.

WOLF
() автор топика
Ответ на: комментарий от WOLF

В общем Спики у меня конечно нет. Я попробовал собрать твое ядро с конфигом для qemu (make vexpress_defconfig) и потом запустить с initramfs, чтобы посмотреть не намудрил ли вендор с патчами.

Сходу не собралось. Добавил в lib/Makefile в 26 строке genalloc.o

obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
	 string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \
	 bsearch.o find_last_bit.o genalloc.o

Я так понял, был какой-то патч, который исправляет эту ошибку, но, возможно с твоим конфигом эта часть не нужна. Добавь тоже, мало ли вдруг в этом дело. Я еще сравню твой конфиг с моим, может докопаюсь до сути.

initramfs собирал так

arm-linux-gnueabi-gcc -static init.c -o init
echo init|cpio -o --format=newc > initramfs

запускал так

qemu-system-arm -M vexpress-a9 -kernel ../spica-linux-3.0-android-s3c64xx/arch/arm/boot/zImage -initrd initramfs -serial stdio -append "console=tty1"

Все собралось, elf-файл выполнился, вывод на консоль есть.

Код файла init.c на всякий случай.

#include <stdio.h>
 
void main() {
  printf("Hello World!\n");
  while(1);
}
tlx ★★★★★
()
Ответ на: комментарий от tlx

Я собираю initramfs с помощью initramfs_list.

Вот лог ядра с UART (пришлось немного помучится, чтобы к нему подключится): http://pastebin.com/zg3QASKe

Я ошибок здесь не вижу.

Может тебе удалось потому, что у тебя initramfs не вшита в ядро?

WOLF
() автор топика
Ответ на: комментарий от WOLF

Может тебе удалось потому, что у тебя initramfs не вшита в ядро?

Вроде получилось.

Насчет genalloc.o: дело было конфигах. У меня был отключен CONFIG_GENERIC_ALLOCATOR, у тебя он включен.

В общем я создал пустой каталог, положил туда тот же бинарник. Потом так:

mkdir dev
cd dev
sudo mknod -m 622 console c 5 1
sudo mknod -m 622 tty0 c 4 0

Указал путь в CONFIG_INITRAMFS_SOURCE.

До создания узлов в dev запуск командой

qemu-system-arm -M vexpress-a9 -kernel arch/arm/boot/zImage -serial stdio -append "console=tty1"

не доходил до старта бинарника (тоже без видимых ошибок), после создания заработало.

tlx ★★★★★
()
Последнее исправление: tlx (всего исправлений: 2)
Ответ на: комментарий от WOLF

Смотрю конфиги:

У меня CONFIG_CMDLINE_FROM_BOOTLOADER включен и я добавляю «console=tty1». Понятно, что у тебя загрузчик закрыт, но в твоем initramfs_list файл init лежит в корне, а в командной строке init=/sbin/init. Не знаю как нумеруются консоли, но у тебя console=tty0, у меня tty1.

Бросились в глаза: CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 и их отсутствие в твоем. Не уверен в их необходимости, но мало ли.

tlx ★★★★★
()
Ответ на: комментарий от WOLF

Посмотри как в init/noinitramfs.c создается dev/console. Можно скопировать код в initramfs.c если совсем ничего не будет помогать.

Попробуй ради интереса собрать с отключенной CONFIG_KEXEC. Напиши инициализируется ли консоль без нее. Карты памяти у разных SoC разные, может как раз срабатывает условие в intramfs.c

tlx ★★★★★
()
Последнее исправление: tlx (всего исправлений: 1)
Ответ на: комментарий от tlx

В логе бутлоадера уже видно, что я сменил консоль. console=ttySAC0,115200 console=ttySAC1,115200 console=ttySAC2,115200 console=tty0 earlyprintk Вроде я tty0 всегда пользовался.

Можешь кинуть листинг директории с initramfs?

Т.к. без initramfs ядро прекрасно пишет на экран, я не думаю, что конфиг неверный.

WOLF
() автор топика
Ответ на: комментарий от WOLF

Она осталась на работе.

Там ни чего нет кроме бинарника и dev с двумя узлами, про которые я писал.

tlx ★★★★★
()
Ответ на: комментарий от tlx

Ошибка?

У тебя

sudo mknod -m 622 tty0 c 4 0
но при этом
-append "console=tty1"
Это ошибка или опечатка? Я вернулся к этой проблеме (время появилось), но пока нет результатов.

WOLF
() автор топика
Ответ на: Ошибка? от WOLF

Этот пример я взял из блога balau82.

tty0, как я понял, это UART. Вывод в него отображается в сессии терминала, в котором выполняется команда qemu.

При этом tty1 связана с fbcon, которая отображается в отдельном графическом окне.

tlx ★★★★★
()
Последнее исправление: tlx (всего исправлений: 1)
Ответ на: комментарий от tlx

Собрал initramfs из openembedded, воткнул в ядро - ничего. Даже с udev внутри.

Кстати, размер раздела с ядром 5 МБ, что радует.

WOLF
() автор топика
Ответ на: комментарий от WOLF

Я не читал всю ветку на 4pda. У тебя получился dual boot и ты сейчас расширяешь функционал? Или тебе просто нужна менюшка до kexec? Давай прямо в ядро ее добавим?

tlx ★★★★★
()
13 мая 2014 г.
Ответ на: комментарий от tlx

Сейчас телефон шьётся ядром с рекавери, в которой есть терминал и для загрузки Linux используется bash скрипт.

Минусы: это основное ядро и не вариант под каждый кастом его собирать заново с kexec.

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

WOLF
() автор топика
Ответ на: комментарий от WOLF

Я был немного не в теме насчёт kexec. Это же не просто системный вызов а целый бинарник. Всё равно придётся его куда-то класть. Вообще надо покопаться в исходниках может там просто обертка.

Может чёрт с ней со Спикой, возьми телефон для которого собираются boot.img и время на загрузке сэкономишь. Аппарат староват в любом случае.

tlx ★★★★★
()
Ответ на: комментарий от tlx

Вот я его и кладу в initramfs.

Кстати, я сегодня спаял JIG с UARTом. Работает. Попробую на него перенаправить консоль ядра, может прокатит.

WOLF
() автор топика
Ответ на: комментарий от WOLF

Удачи.

Почему бы не написать в Самсунг. Ни каких корпоративных секретов в добавлении initramfs, думаю, нет.

tlx ★★★★★
()
Ответ на: комментарий от tlx

Вроде у меня что-то получилось. По крайней мере иногда я могу лицезреть пингвина на экране. До сих пор всё это зависит от фазы луны. Саму консоль я так и не увидел.

WOLF
() автор топика
Ответ на: комментарий от WOLF

До сих пор всё это зависит от фазы луны

Что-то не успевает инициализироваться. Попробуй вставить какие-нибудь задержки. Мне пару раз помогало.

tlx ★★★★★
()
Ответ на: комментарий от tlx

Мне приходила такая мысль, но как выставить задержки? И как определить порядок инициализации модулей?

WOLF
() автор топика
Ответ на: комментарий от WOLF

как выставить задержки?

Когда я копался в ядре (без SMP), просто крутил циклы подлиньше в разных местах. В твоем случае, смотри где инициализируются блочные устройства и консоль.

Я всё делал методом тыка, так что мануалом поделиться не могу, но модули в ядре 2.6.32 (так же и в 3.0) я отключал в цикле:

  for (fn = __early_initcall_end; fn < __initcall_end; fn++)

Не знаю поможет тебе это или нет. Указатели на функции инициализации модулей кладутся в секцию между этими двумя метками. Боюсь соврать, но вроде порядок зависит от последовательности сборки.

Есть цикл, начинающийся с __initcall_start, и еще какие-то. Всё зависит от того как была экспортирована функция инициализации модуля.

tlx ★★★★★
()
Ответ на: комментарий от tlx

Я загрузил ядро с максимальным loglevel. Логи ядра, где лого появляется, не отличаются от тех, где чёрный экран. Теперь, я нашёл способ получить лого на экране: вставляю батарею, подключаю кабель, телефон сам начинает включаться, лого есть. После этого, когда он перезагружается (паника?) лого уже не появляется. Получается, что он из-за initramfs начал слишком быстро грузиться до консоли. Но экран то уже инициализирован бутлоадером, в чём разница. Кстати, если врубить console=tty0, то фишка с лого перестаёт работать, шаманство всё равно выдаёт чёрный экран.

WOLF
() автор топика
Ответ на: комментарий от WOLF

После этого, когда он перезагружается (паника?)

В SoC ребут ребуту рознь. Там идет запись в регистр, который сохраняет состояние во время перезагрузки. Указатель на функцию, специфичную для оборудования, присваивается указателю arm_pm_restart (arm_pm_restart = mdesc->restart). Для тегры она присваивается как то так:

.restart	= tegra_assert_system_reset, 

Внутри Android вызывается системным вызовом:

case ANDROID_RB_RESTART2:
  ret = __reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_RESTART2, arg);
...
ENTRY(__reboot)
    .save   {r4, r7}
    stmfd   sp!, {r4, r7}
    ldr     r7, =__NR_reboot
    swi     #0
    ldmfd   sp!, {r4, r7}
    movs    r0, r0
    bxpl    lr
    b       __set_syscall_errno
END(__reboot)

В общем если хочешь получать лого после спонтанных перезагрузок, думаю надо добавить в функцию panic() логику нормальной перезагрузки.

tlx ★★★★★
()
17 августа 2014 г.
Ответ на: комментарий от tlx

Поднял консольку на экране. До сих пор стартует с какими-то шаманствами. Без подключения кабелем к ПК не стартует вовсе. С подключённым стартует один раз и то, если подключить в какой-то определённый момент. При этом сам драйвер OTG вываливается с печатью дампа. Говорит, ошибка здесь: https://github.com/LONELY-WOLF/spica-linux-3.0/blob/android-s3c64xx/drivers/u... Хотел уже пробовать скрипт-меню писать, но без консоли по USB это будет гемором. Шить каждый раз ядро...

З.Ы. кажись, дело было в udev. Вроде как после его старта консоль появляется.

WOLF
() автор топика
Ответ на: комментарий от WOLF

кстати, включи себе CONFIG_DEVTMPFS. очень удобная штука для рамдиска - монтирует при старте /dev и заполняет нодами без участия бут-скрипта

касательно фреймбуфферной консоли. поищи в исходниках драйвера фреймбуффера и в своей борде строку «_initcall». _initcall задаёт функции, которые вызываются на разных этапах инициализации ядра. возможно, фреймбуффер использует rootfs_initcall, device_initcall, late_initcall, которые вызываются после монтирования рута. попробуй тогда subsys_initcall.

anonymous
()
Ответ на: комментарий от WOLF

Думаю на этом стоит закончить. Судя по мощности проца, ты и так тратишь кучу времени на ожидание загрузки.

Скоро появятся смарты на ARMv8. Может пора перейти на какой-нибуди из них?

tlx ★★★★★
()
Ответ на: комментарий от anonymous

1) Естественно, она включена, т.к. её требует udev

2) В описании ясно сказано, что в случае initramfs это не работает

WOLF
() автор топика
Ответ на: комментарий от tlx

Система грузится 22 секунды.

Я хотел перейти на другой тел, но Сосунг отменил выпуск своего Tizen смарта. Спика же у меня валяется, чего бы её не помучать. Практика показала, что наработки легко переносятся на другую машину. Уже 2 платы получили OE в качестве ОС :)

WOLF
() автор топика
Ответ на: комментарий от anonymous

Что именно?

Действительно, tty0 - текущая tty (для монитора?). А tty - текущая tty для процесса. /dev/console ранее был симлинком (видать для поддержки нескольких консолей его переделали в драйвер). Вот, что говорится про консоли в документации:

Virtual consoles and the console device

Virtual consoles are full-screen terminal displays on the system video monitor. Virtual consoles are named /dev/tty#, with numbering starting at /dev/tty1; /dev/tty0 is the current virtual console. /dev/tty0 is the device that should be used to access the system video card on those architectures for which the frame buffer devices (/dev/fb*) are not applicable. Do not use /dev/console for this purpose.

The console device, /dev/console, is the device to which system messages should be sent, and on which logins should be permitted in single-user mode. Starting with Linux 2.1.71, /dev/console is managed by the kernel; for previous versions it should be a symbolic link to either /dev/tty0, a specific virtual console such as /dev/tty1, or to a serial port primary (tty*, not cu*) device, depending on the configuration of the system.

WOLF
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.