После завершения проекта Interactive Bootloader пришла идея, что за место логотипа бутлоадера и бутанимации можно на экран выводить ядерные логи. Причём вывод этих логов можно реализовать на самом раннем этапе работы Linux-ядра из-за чего время показа логотипа бутлоадера будет совсем ничтожным.
Перед началом рассказа о LLCON стоит упомянуть о FRAMEBUFFER_CONSOLE. Данная опция Linux-ядра включает функционал по выводу ядерных логов на экран устройства. Но данный функционал начинает свою работу только после инициализации видео-драйверов и драйвера самой FRAMEBUFFER консоли. И поэтому большинство ядерных логов просто напросто не отображается, а логотип бутлоадера отображается очень значительное время. Поэтому на стандартную FRAMEBUFFER консоль даже и не стоит смотреть, т.к. время её работы довольно короткое.
Т.к. функционал низкоуровневого отображения символов мне уже приходилось реализовывать в IBL, то данный функционал частично был перенесён в LLCON.
Для работы LLCON достаточно в командной строке Linux-ядра указать следующее:
Расшифровка параметров:
mode:
0 = LLCON отключён
1 = синхронный вывод логов (постраничный скроллинг)
2 = асинхронный вывод логов (построчный скроллинг)
delay:
Задержка в милисекундах.
Данная задержка используется в потоке, выводящем графику на экран.
Рекомендуемое значение: 100.
textwrap:
0 = перенос текста на новые строки запрещён
1 = перенос текста на новые строки разрешён
fb_addr:
Физический адрес FrameBuffer. Узнать этот адрес можно в DeviceTree.
(см. параметр "qcom,memblock-reserve" в ветке "qcom,mdss_fb_primary")
fb_bpp:
Формат пикселей дисплея.
Данный параметр не используется.
fb_height:
Высота дисплея в пикселях.
fb_width:
Ширина дисплея в пикселях.
fb_stride:
Размер одной строки в пикселях или в байтах.
font_size:
Размер шрифта. Поддерживаемые значения: 6, 8, 10, 12.
Каждый шрифт нужно отдельно подключать в def_config.
font_color:
Цвет символов в HEX формате RGB888.
Пример заполнения параметров:
Сразу стоит отметить, что функцинал LLCON позволяет использовать значение fb_addr взятое из DeviceTree. При этом значение из командной строки просто игнорируется. Для этого Linux-ядро нужно пропатчить таким вот образом:
Стоит отметить, что при добавлении LLCON в ядро следует включить следующие опции:
Для того, что бы LLCON не конфликтовал с MDSS драйвером, занимающимся выводом графики, нужно вовремя этот самый LLCON отключить. Для этого нужно немного пропатчить MDSS драйвер:
Так же стоит отметить, что Android оболочке нужно сообщить о том, что при работе LLCON не следует пытаться выводить на экран устройства бутанимацию. Для этого нужно уже патчить код не ядра, а код init модуля. Ссылка на сам патч: github.com
Ограничения текущей версии LLCON:
Исходники LLCON:
Демонстрация работы
LLCON 1 - постраничный режим, шрифт 6x11:
LLCON 2 - построчный режим, шрифт 8x16:
Перед началом рассказа о LLCON стоит упомянуть о FRAMEBUFFER_CONSOLE. Данная опция Linux-ядра включает функционал по выводу ядерных логов на экран устройства. Но данный функционал начинает свою работу только после инициализации видео-драйверов и драйвера самой FRAMEBUFFER консоли. И поэтому большинство ядерных логов просто напросто не отображается, а логотип бутлоадера отображается очень значительное время. Поэтому на стандартную FRAMEBUFFER консоль даже и не стоит смотреть, т.к. время её работы довольно короткое.
Т.к. функционал низкоуровневого отображения символов мне уже приходилось реализовывать в IBL, то данный функционал частично был перенесён в LLCON.
Для работы LLCON достаточно в командной строке Linux-ядра указать следующее:
androidboot.llcon=<mode>,<delay>,<textwrap>,<fb_addr>,<fb_bpp>,<fb_height>,<fb_width>,<fb_stride>,<font_size>,<font_color>
Расшифровка параметров:
mode:
0 = LLCON отключён
1 = синхронный вывод логов (постраничный скроллинг)
2 = асинхронный вывод логов (построчный скроллинг)
delay:
Задержка в милисекундах.
Данная задержка используется в потоке, выводящем графику на экран.
Рекомендуемое значение: 100.
textwrap:
0 = перенос текста на новые строки запрещён
1 = перенос текста на новые строки разрешён
fb_addr:
Физический адрес FrameBuffer. Узнать этот адрес можно в DeviceTree.
(см. параметр "qcom,memblock-reserve" в ветке "qcom,mdss_fb_primary")
fb_bpp:
Формат пикселей дисплея.
Данный параметр не используется.
fb_height:
Высота дисплея в пикселях.
fb_width:
Ширина дисплея в пикселях.
fb_stride:
Размер одной строки в пикселях или в байтах.
font_size:
Размер шрифта. Поддерживаемые значения: 6, 8, 10, 12.
Каждый шрифт нужно отдельно подключать в def_config.
font_color:
Цвет символов в HEX формате RGB888.
Пример заполнения параметров:
androidboot.llcon=2,100,0,0x03200000,24,1280,720,720,8,0xFFFFFF
Сразу стоит отметить, что функцинал LLCON позволяет использовать значение fb_addr взятое из DeviceTree. При этом значение из командной строки просто игнорируется. Для этого Linux-ядро нужно пропатчить таким вот образом:
int __init dt_scan_for_memory_reserve(unsigned long node, const char *uname, int depth, void *data) { char *memory_name_prop; unsigned int *memory_remove_prop; .... mem_reserve: if (memory_reserve_prop) { if (memory_reserve_prop_length != (2*sizeof(unsigned int))) { WARN(1, "Memory reserve malformed\n"); goto out; } memory_start = be32_to_cpu(memory_reserve_prop[0]); memory_size = be32_to_cpu(memory_reserve_prop[1]); ret = memblock_reserve(memory_start, memory_size); if (ret) WARN(1, "Failed to reserve memory %x-%x\n", memory_start, memory_start+memory_size); else pr_info("Node %s memblock_reserve memory %x-%x\n", uname, memory_start, memory_start+memory_size); #ifdef CONFIG_LLCON if (!ret && strcmp(uname, "qcom,mdss_fb_primary") == 0) { llcon_set_fb_addr((void *)memory_start, memory_size); } #endif } out: return 0; }
Стоит отметить, что при добавлении LLCON в ядро следует включить следующие опции:
CONFIG_VT=y CONFIG_LLCON=y CONFIG_FONTS=y CONFIG_FONT_6x11=y CONFIG_FONT_8x16=y CONFIG_FONT_SUN12x22=yПри этом можно включать только необходимые вам наборы шрифтов.
Для того, что бы LLCON не конфликтовал с MDSS драйвером, занимающимся выводом графики, нужно вовремя этот самый LLCON отключить. Для этого нужно немного пропатчить MDSS драйвер:
static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct msm_fb_data_type *mfd; void __user *argp = (void __user *)arg; struct mdp_page_protection fb_page_protection; int ret = -ENOSYS; struct mdp_buf_sync buf_sync; struct msm_sync_pt_data *sync_pt_data = NULL; unsigned int dsi_mode = 0; if (!info || !info->par) return -EINVAL; mfd = (struct msm_fb_data_type *)info->par; if (!mfd) return -EINVAL; if (mfd->shutdown_pending) return -EPERM; #ifdef CONFIG_LLCON if ( cmd != MSMFB_NOTIFY_UPDATE && cmd != MSMFB_OVERLAY_VSYNC_CTRL && cmd != MSMFB_METADATA_GET && cmd != MSMFB_DISPLAY_COMMIT ) { llcon_exit(); } #endif atomic_inc(&mfd->ioctl_ref_cnt); mdss_fb_power_setting_idle(mfd); .... exit: if (!atomic_dec_return(&mfd->ioctl_ref_cnt)) wake_up_all(&mfd->ioctl_q); return ret; }
Так же стоит отметить, что Android оболочке нужно сообщить о том, что при работе LLCON не следует пытаться выводить на экран устройства бутанимацию. Для этого нужно уже патчить код не ядра, а код init модуля. Ссылка на сам патч: github.com
Ограничения текущей версии LLCON:
- поддерживаются только дисплеи RGB888 (24-bit)
- поддерживаются дисплеи с нормальной ориентацией
- поддерживается только Qualcomm платформа
Исходники LLCON:
Демонстрация работы
LLCON 1 - постраничный режим, шрифт 6x11:
LLCON 2 - построчный режим, шрифт 8x16:
Комментариев нет:
Отправить комментарий