image

К огромному сожалению, старые смартфоны всё чаще и чаще находят своё пристанище в мусорном баке. К прошлым, надежным «друзьям» действует исключительно потребительское отношение — чуть устарел и сразу выкинули, словно это ненужный мусор. И ведь люди даже не хотят попытаться придумать какое-либо применение гаджетам прошлых лет! Отчасти, это вина корпораций — Google намеренно тормозит и добивает довольно шустрые девайсы. Отчасти — вина программистов, которые преследуют исключительно бизнес-задачи и не думают об оптимизации приложений совсем. В один день я почувствовал себя Тайлером Дёрденом от мира IT и решил бросить вызов проприетарщине: написать свою прошивку для уже существующего смартфона с нуля. А дабы задачка была ещё интереснее, я выбрал очень распространенную и дешевую модель из 2012 года — Fly IQ245 (цена на барахолках — 200-300 рублей). Кроме того, у этого телефона есть сразу несколько внешних шин, к которым можно подключить компьютер или микроконтроллер, что даёт возможность использовать его в качестве ультрадешевого одноплатника для DIY-проектов. Получилось ли у меня реализовать свои хотелки? Читайте в статье!

Мотивация


Честно сказать, идея попытаться реализовать свою прошивку мне пришла ещё давно. Однако, дабы не завлекать опытного читателя кликбейтом, я сразу поясню, в чём заключается «прошивка с нуля»:

  1. Мы всё ещё используем Linux: в качестве ядра мы продолжаем использовать образ Linux, предоставленный нам производителем. Написание прошивки полностью с нуля заняло бы очень много времени (особенно без схемы на устройство). Однако, мы вообще не загружаем Android никаким образом.
  2. Мы не используем библиотеки AOSP: наша прошивка без необходимости не использует никаких библиотек уже имеющегося образа Android. Вся работа с железом происходит с помощью низкоуровневого API Linux. Это значит, что отрисовка графики, звук, управление ресурсами и питанием ложится полностью на нас.
  3. Прошивка может запускать только нативные программы: да, это тоже камень в сторону Android. Изначально, наша прошивка умеет запускать только нативные программы, написанные на C. Причём она экспортирует собственное C API — дабы приложения могли использовать всю мощь нашего смартфона в виде простого и понятного набора методов.

image

Проектов по выкидыванию Android из, собственно, Android-смартфонов как минимум несколько: UBPorts — бывший Ubuntu Touch, FireFox OS и его наследник Kai OS и конечно же, postmarketOS. Отчасти можно сюда отнести и Sailfish OS — но там образы имеются в основном на смартфоны от Sony. Все эти проекты объединяет сложность портирования и невозможность их завести на устройствах без исходного кода ядра. Даже если у вас есть исходный код ядра, но, например, устройство использует ядро 2.6 — навряд-ли вы сможете завести современный дистрибутив на нём.

image

Другой вопрос в том, что можно использовать полу-baremetal подход, когда от Linux берется практически минимальный функционал. Всё, что мы имеем — busybox, libc и низкоуровневый доступ к железу, благодаря API самого ядра. Как под это всё программировать — я рассказывал в прошлой статье. Этот же подход мы будем использовать и сейчас — как иллюстрация реального применения подобного способа.

Итак, что наша прошивка должна уметь:

  • Отрисовывать произвольную графику: графическая подсистема нашей прошивки должна работать с фиксированным форматом пикселя, уметь загружать прозрачные и непрозрачные изображения, отрисовывать картинки с альфа-блендингом и т. п.
  • Уметь звонить и работать с модемом: общение с модемом происходит посредством AT-команд — общепринятого в индустрии стандарта. Однако в случае нашего устройства, есть м-а-а-а-ленький нюанс, о котором я расскажу позже.
  • Иметь механизм приложений: мы ведь не будем хардкодить все «экраны» в прошивке в виде кучи стейтов, верно? Для этого у нас должен быть простой и понятный механизм слинкованных с прошивкой приложений.
  • Обрабатывать ввод: обработка тачскрина и жестов — это задача подсистемы ввода.
  • Реализовывать анимированный UI: здесь всё очевидно, наша прошивка должна иметь готовые элементы пользовательского интерфейса для будущих приложений: кнопки, текстовые поля и т. д. О деталях реализации этой подсистемы, я расскажу ниже (а реализовал я её очень необычно для такой системы).

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

Аппаратная часть


В качестве смартфона для нашего проекта, я выбрал популярную бюджетную модель из 2012 года — Fly IQ245 Wizard. Это простенький китайский смартфон, который работал на базе популярного в прошлом 2G-чипсета: MediaTek MT6573, да и стоил около 2х тысяч рублей новым. Однако вот в чём суть: мне удалось заставить работать «медиатековский» модем и даже позвонить с него на свой основной телефон, но… только ввод и вывод данных из звукового тракта модема происходит через звуковую подсистему Android — к которой доступа у нас нет!

image

image

Именно поэтому, мы идём на очень хитрый и занимательный костыль: мы распаяем внешний модем сами! В качестве радиомодуля у нас выступит модуль SIM800 от компании SIMCOM. И даже он очень близок к нашему смартфону в аппаратном плане: ведь в основе этого модуля лежит популярнейший чипсет из кнопочников тех лет: MediaTek MT6261D. Преимущество SIM800 в его цене — он стоит пару сотен рублей, так что по карману выбор модема не влияет.

image
На весу паять крайне неудобно. В финальном варианте перепаяю нормально.

Но как его подключать? SIM800 общается с другими устройствами посредством протокола UART — универсальный асинхронный приемо-передатчик. И вот тут мы включаем смекалочку. Разбираем устройство и видим то, что я пытаюсь долгое время донести до моих читателей — аж два канала UART: один практически посередине, второй справа. Нам нужны пятачки TXD4 и RXD4:

image

image

Обычно на этот канал UART летят логи ядра, которые можно без проблем отключить минорной правкой U-Boot в HEX-редакторе. Впрочем, модем никак не реагирует на «мусор» из консоли и просто отвечает ошибками — хватит лишь очистить буфер сообщений для того, чтобы все работало нормально. Подпаиваемся к UART'у с помощью преобразователя — у меня оным выступает ESP32 с выпаянным чипом.

image

image

Увидели логи? Замечательно, пора попытаться что-то отправить на ПК и с ПК. UART работают без тактовых сигналов и зависит исключительно от старт/стоп битов и бодрейта, который на устройствах MediaTek равен 921600. TXD4 и RXD4 обнаруживаются в системе на консоли /dev/ttyMT3. Пробуем что-то отправить: всё работает!

image

Вот теперь-то можно подключить наш внешний модем и попытаться пообщаться с ним, отправив тестовую команду AT. Модем отвечает OK! На этот раз я работаю с смартфоном из режима Factory mode — практически тоже самое, что и режим recovery, но позволяющий, например, получить доступ к камере устройства. Простая и понятная схема, поясняющая что и куда подключать:

image

На этом модификация аппаратной части пока закончена. Пора переходить к реализации софта! Я решил разделить материал на каждый модуль, который я реализовывал — дабы вам был понятен процесс разработки и отладки прошивки!

Заставляем смартфон запускать нашу прошивку


На этот раз я решил загружать смартфон из режима рекавери. Однако никто не мешает в будущем просто прошить раздел recovery вместо boot и получить прямую загрузку прямо в нашу прошивку. Время такой загрузки будет занимать ~3-4 секунды с холодного старта. Очень даже ничего.

image

Я взял уже готовый образ TWRP для своего смартфона и пропатчил его, дабы сам рекавери не мешал своим интерфейсом. Для этого я распаковал образ recovery.img с помощью MtkImgTools и убрал в init.rc запуск службы /sbin/recovery. После этого, я залил прошивку обратно на устройство и получил подобную свободу действий — консоль через USB и чистый холст в виде смартфона! Старые смартфоны на чипсетах MediaTek шьются через USB только после замыкания тест-поинта — на моем аппарате его местонахождение очевидно. Замыкаем контакты между собой, подключаем смартфон без АКБ к ПК и ждем прошивки:

image

Теперь можно деплоить программы! Важный нюанс: в отличии от Makefile из прошлой статьи, для Android 2.3 параметр -fPIE нужно убрать — иначе динамический линкер (/sbin/linker) будет вылетать в segmentation fault.

image

Графическая подсистема


В комментариях под прошлой статьёй меня похвалили за то, что я делюсь достаточно профильными знаниями касательно эффективной отрисовки 2D-графики. Собственно, к реализации графической подсистемы я подошёл ответственно и постарался реализовать достаточно шустрый рендерер, к которому затем можно подключить другие модули.

image

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

В случае с этим устройством (и большинством старых устройств), формат пикселя оказался RGB565 — т. е. 5 бит красный, 6 бит зеленый, 5 бит синий. Конвертация форматов пикселей всегда была занозой в заднице для программных рендереров, поскольку занимает дополнительное время, которое обратно зависимо от размера дисплея. Изначально я решил выделить буфер в том же формате, что и фреймбуфер, но затем решил сделать классический и самый портативный формат — RGB888 (24х-битный цвет), а при копировании кадра на экран, на лету делать преобразования цвета:

void CGraphics::Flip()
{
    for(int i = 0; i < fbDesc.width; i++)
    {
        for(int j = 0; j < fbDesc.height; j++)
        {
            short* absPixel = (short*)&fbDesc.pixels[(j * fbDesc.lineLength) + (i * 2)];
            char* absBackPixel = &backBuffer[(j * fbDesc.width + i) * 3];

            short c16 = ((absBackPixel[0] & 0b11111000) << 8) | ((absBackPixel[1] & 0b11111100) << 3) | (absBackPixel[2] >> 3);
            *absPixel = c16;
        }
    }

    // We should pass a bit changed VSCREENINFO structure back to FB driver, to make it update our screen
    // This seems like a bit non-standard behaviour, because Android recovery uses this too: probably, something to save power.
    flip = !flip;
    vInfo.yres_virtual = (int)flip;
    ioctl(fbDev, FBIOPUT_VSCREENINFO, &vInfo);
}

Очень важный нюанс, который я не упомянул в предыдущей статье: на устройствах прошлых лет для обновления фреймбуфера необходимо послать структуру var_screeninfo, где хотя бы что-то изменено, иначе никаких изменений мы не увидим. Этот же костыль используется в родном recovery для отрисовки, а судя по исходникам драйвера fb, «правильный» способ обновить экран — послать драйверу ioctl (который я пока что не пробовал).

После того, как я смог управлять дисплеем, я решил загрузить и отобразить какую-нибудь картинку. Пусть это будут обои для нашей прошивки:

FILE* f = fopen(fileName, "r");
	
    LOGF("Loading %s\n", fileName);

	if(!f)
	{
        LOGF("Unable to open %s\n", fileName);
		return 0;
	}

	CTgaHeader hdr;
	fread(&hdr, sizeof(hdr), 1, f);

	if(hdr.paletteType)
	{
		LOG("Palette images are unsupported\n");
		return 0;
	}
	
	if(hdr.bpp != 24 && hdr.bpp != 32)
	{
		LOG("Unsupported BPP\n");
		return 0;
	}

	unsigned char* buf = (unsigned char*)malloc(hdr.width * hdr.height * (hdr.bpp / 8));
	
    if(!buf)
    {
        LOG("Memory exhausted\n");
        return 0;
    }

	//fseek(f, hdr.headerLength, SEEK_SET);

	fread(buf, hdr.width * hdr.height * (hdr.bpp / 8), 1, f);
	fclose(f);
	CImage* ret = new CImage();
	ret->Width = hdr.width;
	ret->Height = hdr.height;
	ret->Pixels = buf;
    ret->IsTransparent = hdr.bpp == 32;

	LOGF("Loaded %s %ix%i\n", fileName, ret->Width, ret->Height);
	return ret;

Загрузчик TGA сильно не поменялся: я таскаю его в неизменном виде из проекта в проект. Он поддерживает любые форматы пикселя, кроме палитровых, но я его искусственн ограничиваю на RGB888 и RGBA8888 — для поддержки обычных картинок и картинок с альфа-каналом. После этого, я написал не очень шустрые, но достаточно универсальные методы для отрисовки картинок:

__inline void __ClipPrimitive(CFrameBuffer* fbDesc, int* dw, int* dh)
{
    if(*dw > fbDesc->width)
        *dw = fbDesc->width - 1;

    if(*dh > fbDesc->height)
        *dh = fbDesc->height - 1;
}

void CGraphics::PutPixel(int x, int y, CColor color)
{
    if(x < 0 || y < 0)
        return;
    
    char* col = &backBuffer[(y * fbDesc.width + x) * 3];
    col[0] = color.R;
    col[1] = color.G;
    col[2] = color.B;
}

void CGraphics::PutPixelAlpha(int x, int y, CColor color, float alpha)
{
    if(x < 0 || y < 0)
        return;
    
    char* col = &backBuffer[(y * fbDesc.width + x) * 3];

    col[0] = (byte)(color.R * alpha + col[0] * (1.0f - alpha));
	col[1] = (byte)(color.G * alpha + col[1] * (1.0f - alpha));
	col[2] = (byte)(color.B * alpha + col[2] * (1.0f - alpha));
}

void CGraphics::DrawImage(CImage* img, int x, int y)
{
    if(img)
    {
        if(!img->IsTransparent)
        {
            for(int i = 0; i < img->Height; i++)
            {
                for(int j = 0; j < img->Width; j++)
                {
                    if(j >= fbDesc.width)
                        break;

                    CColor col;
                    unsigned char* pixels = &img->Pixels[((img->Height - i - 1) * img->Width + j) * 3];

                    col.R = pixels[2];
                    col.G = pixels[1];
                    col.B = pixels[0];

                    PutPixel(x + j, y + i, col);
                }

                if(i >= fbDesc.height)
                    break;
            }
        }
        else
        {
            for(int i = 0; i < img->Height; i++)
            {
                for(int j = 0; j < img->Width; j++)
                {
                    if(j >= fbDesc.width)
                        break;

                    CColor col;
                    unsigned char* pixels = &img->Pixels[((img->Height - i - 1) * img->Width + j) * 4];

                    col.R = pixels[2];
                    col.G = pixels[1];
                    col.B = pixels[0];
                    float alpha = (float)pixels[3] / 255;

                    PutPixelAlpha(x + j, y + i, col, alpha);
                }

                if(i >= fbDesc.height)
                    break;
            }
        }
    }
}

PutPixel желательно заинлайнить в будущем. В целом, сама отрисовка работает достаточно быстро, но поскольку рендеринг выполняется на ЦПУ — рано или поздно мы упремся в количество картинок на экране. Есть некоторые оптимизации: например, непрозрачные картинки можно просто коприовать сканлайнами прямо в задний буфер.

Сразу же реализовываем методы для рисования шрифтов: они у нас будут совсем простенькими — только моноширинные (все символы имеют одинаковую ширину) и растровыми (для каждого размера придется «запекать» несколько шрифтов). Для этого я написал маленькую программку, которая рисует виндовые шрифты прямо в наш самопальный формат:

            Console.WriteLine("FontBake for BodyaPhone");
            Console.WriteLine("(C)2023 Bogdan Nikolaev");

            if (args.Length > 0)
            {
                string fontName = args[0];
                int glyphSize = 16;
                Font fnt = new Font(fontName, glyphSize, FontStyle.Bold, GraphicsUnit.Pixel);
                SolidBrush brush = new SolidBrush(Color.White);
                SolidBrush bg = new SolidBrush(Color.Magenta);

                Bitmap glyph = new Bitmap(glyphSize, glyphSize);
                Graphics g = Graphics.FromImage(glyph);
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

                BinaryWriter writer = new BinaryWriter(File.Create(fontName));
                writer.Write(glyphSize); // Glyph size

                byte[] glyphData = new byte[glyphSize * glyphSize * 3];

                for(int i = 0; i < 255; i++)
                {
                    g.FillRectangle(bg, 0, 0, glyphSize, glyphSize);
                    g.DrawString(((char)i).ToString(), fnt, brush, PointF.Empty);

                    var data = glyph.LockBits(new Rectangle(0, 0, glyphSize, glyphSize), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                    System.Runtime.InteropServices.Marshal.Copy(data.Scan0, glyphData, 0, glyphData.Length);
                    glyph.UnlockBits(data);

                    writer.Write(glyphData);
                }
            }

Формат примитивнейший:
1 байт говорит нам о размере шрифта и далее идут 255 изображений символов. Да, это не очень эффективно т.к попадают пустые символы из ASCII-таблицы, но в будущем это можно поправить.
Прозрачность в символах обеспечивает фоновый цвет Magena — ярко-розовый. Я не стал делать дополнительный альфа-канал, т. к. иначе будут серьезные лаги при выводе большого количества текста.

void CGraphics::DrawString(CFont* font, char* str, int x, int y)
{
    CColor col = { 64, 64, 64 };

    DrawStringColored(font, str, x, y, col);
}

void CGraphics::DrawStringColored(CFont* font, char* str, int x, int y, CColor colorMultiply)
{
    if(font && str && strlen(str) > 0)
    {
        
        for(int i = 0; i < strlen(str); i++)
        {
            DrawGlyph(font->Glyphs[str[i]], x + (i * (font->Glyphs[str[i]]->Width - 5)), y, colorMultiply);
        }
    }
}

Теперь у нас есть отображение картинок и текста! Что с этим можно сделать?

Обработка ввода


image

Конечно же, реализовать обработку ввода! Это будет фактически минимальный функционал, который можно использовать для создания UI-приложений. В дополнение к прошлой статье хочу отметить то, что разные драйверы тачскрина ведут себя по разному. На этом устройстве, драйвер тачскрина не сообщал событие BTN_TOUCH, из-за чего пришлось идти на некоторые ухищрения. Однако в конце-концов, метод для проверки касания пальца в определенном месте у меня есть:

void CInput::Update()
{
    input_event ev;
	int ret = 0;
    bool gotEvent = false; // Touchscreen driver sends us events each input "frame". So, if we don't have BTN_TOUCH event, we can track releasing finger when there are no events in current frame.

	while((ret = read(evDev, &ev, sizeof(input_event)) != -1))
	{
		if(ev.code == ABS_MT_POSITION_X)
			TouchX = ev.value;
		
		if(ev.code == ABS_MT_POSITION_Y)
			TouchY = ev.value;

        gotEvent = true;
	}

    bool pressed = gotEvent;

    if(pressed && TouchState == tsIdle)
        TouchState = tsTouching;

    if(TouchState == tsReleased)
        TouchState = tsIdle;

    if(!pressed && TouchState == tsTouching)
        TouchState = tsReleased;
}

bool CInput::IsTouchedAt(int x, int y, int w, int h)
{
    return TouchX > x && TouchY > y && TouchX < x + w && TouchY < y + h && TouchState == tsReleased;
}

Пока что здесь не хватает обработки «хардварных» кнопок — домой, меню, назад и т. п. Однако в будущем это всё можно реализовать!

Анимация


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

Аниматор напоминает оный из ранних версий Android: он имеет фиксированный набор свойств, которые умеет интерполировать в промежутках определенного времени. Если простыми словами: то он оперирует линейными отрезками времени a и b, в промежутке которых мы имеем значение «прогресса» — которое даёт нам результат от 0.0f (начало анимации) до 1.0f (конец анимации). Пока время тикает до необходимого интервала (duration), аниматор интерполирует заранее назначенные ему поля до нужных значений.

Именно так и получается плавность! Похожим образом реализованы анимационные системы во многих играх и мобильных ОС, только там они гораздо более комплексны: есть сериализация/десериализация из файлов, поддержка кейфреймов (несколько последовательных состояний на одном промежутке времени), поддержка кастомных свойств и т. п.

CAnimator::CAnimator()
{
    SetDuration(1.0f);
}

CAnimator::~CAnimator()
{
    
}

void CAnimator::SetTranslation(int xFrom, int yFrom, int xTo, int yTo)
{
    this->xFrom = xFrom;
    this->yFrom = yFrom;
    this->xTo = xTo;
    this->yTo = yTo;
}

void CAnimator::SetRotation(float from, float to)
{
    rFrom = from;
    rTo = to;
}

void CAnimator::SetDuration(float speed)
{
    duration = speed;
}

float lerp(float a, float b, float f)
{
    return a * (1.0 - f) + (b * f);
}

bool CAnimator::Update()
{
    Time += 0.25f;

    if(Time > 1.0f)
        Time = 1.0f;

    X = (int)lerp((float)xFrom, (float)xTo, Time);
    Y = (int)lerp((float)yFrom, (float)yTo, Time);

    Rotation = lerp(rFrom, rTo, Time);
}

void CAnimator::Run()
{
    Time = 0;

    IsPlaying = true;
}

Модем


Как я уже говорил раннее, работа с модемом происходит посредством AT-команд. Лучше всего обрабатывать ввод-вывод модема из отдельного потока, поскольку он может отвечать довольно медленно и тормозить UI-поток основной программы, вызывая лаги. В SIM800 уже реализован весь GSM-стек, в том числе декодирование и вывод звука через встроенный усилитель с фильтром — остается только подключить динамики и микрофон от нашего телефона. Пока что я подсобрал аудиотракт на том, что было под рукой — микрофон от нерабочего смартфона и динамик от планшета, но для проверки этого хватает:

image

Важный нюанс: по умолчанию, tty-устройства в Linux работают по терминальному принципу — т. е. дробят транзакции по символу окончания строки (\n), имеют ограниченный буфер и т. д. Для нормальной работы в условиях модема — когда фактически длина ответа неизвестна, а в сам ответ могут «вклиниваться» Unsolicited-команды (своеобразные флаги о состоянии от модема, которые могут прийти в произвольное время — т. е. при входящем звонке, модем начнёт флудить RING в терминал), необходимо иметь возможность точно прочитать весь буфер до конца и парсить данные «по месту». Для этого используется raw-режим терминала:

tcgetattr(modemFd, &tio);
    tio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    tio.c_oflag &= ~(OPOST);
    tio.c_cflag |= (CS8);
    tio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
	tcsetattr(modemFd, TCSAFLUSH, &tio);

После чего можно запросить состояние модема:

        char atBuf[16];
	// Check modem presence
	SendAT("AT\r\n", 250);
	GetATResponse((char*)&atBuf, sizeof(atBuf));
	
	if(!CheckATStatus((char*)&atBuf))
	{
		printf("Failed to initialize modem: Modem isn't anwered OK\n");
		printf("Modem response: %s\n", &atBuf);
		return;
	}

        LOG("AT = OK, ready to operate\n");

...

void CModem::SendAT(char* command, int waitTime)
{
	int result = write(modemFd, command, strlen(command));

	if(!result)
		LOGF("SendAT failed: %i\n", errno);
	
	usleep(waitTime * 1000);
}

char* CModem::GetATResponse(char* buf, int maxLen)
{
	pollfd pfd;
	pfd.fd = modemFd;
	pfd.events = POLLIN;
	
	memset(buf, 0, maxLen);
	int ev = poll(&pfd, 1, 2000);
	
	if(ev)
	{
		int num = read(modemFd, buf, maxLen);
	}
	else
	{
		LOG("AT Receive: Modem not responding...\n");
	}
}

И продолжить работу дальше. После этого, можно переходить к реализации самой прослойки между модемом и вашей программой:

void CModem::Dial(char* number)
{
	if(strlen(number) > 32)
		return;
	
	char buf[64]; 
	char atResponse[64];
	sprintf((char*)&buf, "ATD%s;\r\n", number);
	LOGF("Dialing %s\n", buf);
	
	SendAT(buf, 250);
	GetATResponse((char*)&atResponse, sizeof(atResponse));
	
	LOGF("Dial response: %s\n", &atResponse);
}

void CModem::Hang()
{
	char atBuf[64];
	
	SendAT("ATH\r\n", 250);
	GetATResponse((char*)&atBuf, sizeof(atBuf));
	LOGF("ATH: %s\n", &atBuf);
	
	LOG("Hang\n");
}

Пытаемся позвонить с помощью метода Dial и видим, что всё работает! Это очень круто! А теперь, конечно же, самое время переходить к реализации того, чего вы ждали — пользовательского интерфейса!

Главный экран


К выбору концепции для интерфейса, я поступил максимально просто — «слизал» дизайн первых версий iOS. Как по мне, это одни из самых красивых версий iOS вообще — все эти приятные градиенты и переливания. Конечно, я не так крут, как инженеры Apple, да и мощного UI-фреймворка у меня пока что нет, поэтому я приступил к реализации с «минимальным» функционалом.

image

Начал я с разделения главного экрана на модули и продумывания архитектуры основного «лаунчера». У нас есть статусбар, который рисуется поверх всех приложений, полка с приложениями — AppDrawer и сами экраны приложений, унаследованные от суперкласса CScreen.

class CScreen
{
protected:
	CAnimator* windowAnimator;
public:
	CScreen();
	~CScreen();

	virtual void Show();
	virtual void Update();
	virtual void Draw();
	virtual void Hide();
};

На данный момент, отрисовка достаточно примитивная: сначала рисуются фоновые обои, затем, если нет никаких активных экранов — AppDrawer и в самом конце рисуется статусбар и всевозможные оверлеи.

void CLauncher::DrawAppDrawer()
{
	for(int i = 0; i < sizeof(Apps) / sizeof(CAppDesc*); i++)
	{
		int x = drawerAnimator->X + (i * 75);
		int y = drawerAnimator->Y;
		Graphics->DrawImage(Apps[i]->Icon, x, y);

		if(Input->IsTouchedAt(x, y, Apps[i]->Icon->Width, Apps[i]->Icon->Height))
		{
			StartScreen(new CDialerScreen());
		}
	}
}

void CLauncher::StartScreen(CScreen* screen)
{
	if(screen)
	{
		currentScreen = screen;
		currentScreen->Show();
	}
}

void CLauncher::Run()
{
	CImage* test = CImage::FromFile("ui/stFiller.tga");;

	while(true)
	{
		Input->Update();

		Graphics->DrawImage(Wallpaper, 0, 0);

		if(currentScreen)
		{
			currentScreen->Update();	
			currentScreen->Draw();
		}
		else
		{
			drawerAnimator->Update();
			DrawAppDrawer();
		}

		Status->Update();
		Status->Draw();
                
                if(Dialog->IsVisible())
		     Dialog->Draw();

		Graphics->Flip();
	}
}

Практически сразу я решил обкатать анимационную «систему» и добавить первые анимашки — выезжающий статусбар и анимация а-ля айфон:

    animator = new CAnimator();
    animator->SetTranslation(0, -imFiller->Height, 0, 0);
    animator->Run();

Выглядит симпатичненько. Если я смогу поднять хардварный GLES, то это получится сделать в разы плавнее и шустрее — не хуже айфонов тех лет! Реализация самого статусбара примитивненькая, но вполне рабочая:

gLauncher->Graphics->DrawImage(imFiller, animator->X, animator->Y);
    gLauncher->Graphics->DrawImage(imBattery[(int)gLauncher->PowerManager->GetBatteryLevel()], imFiller->Width - imBattery[0]->Width - 5, animator->Y + 5);

    char timeFmt[64];
    time_t _time = time(0);
    tm* _localTime = localtime(&_time);
    strftime((char*)&timeFmt, sizeof(timeFmt), "%R", _localTime);

    gLauncher->Graphics->DrawString(gLauncher->Font, (char*)&timeFmt, 0, 0);

Кроме этого, я сразу же реализовал предварительный механизм приложений в системе — пока что они слинкованы статически с основным лаунчером. Для этого есть структура CAppDesc, которая содержит минимально-необходимую информацию для показа информации о приложении и фабрику для создания его основного экрана.

#define APP_FACTORY(clazz) CScreen* __phone_factory_##clazz () { return new clazz (); }

struct CAppDesc
{
	char Name[16];
	char IconPath[32];

	CImage* Icon;
	CScreen* MainScreen;

	CScreen*(*Factory)();
};

...

CAppDesc _APhone = {
	"Phone",
	"ui/phone.tga",
	
	0,
	0,

	&__phone_factory_CDialerScreen
};

После этого, я приступил к реализации первого приложений — собственно, звонилки. :)

#include <monohome.h>

CDialerScreen::CDialerScreen()
{
    dialerButton = CImage::FromFile("ui/dialer_btn.tga");

    memset(&number, 0, sizeof(number));
}

CDialerScreen::~CDialerScreen()
{
    delete dialerButton;
}

void CDialerScreen::Update()
{
    CScreen::Update();
}

bool DialerButton(CImage* img, int x, int y, char* str)
{
    bool state = CGUI::Button(img, x, y);
    gLauncher->Graphics->DrawString(gLauncher->Font, str, x + (img->Width / 2) - 8, y + (img->Height / 2) - 8);

    return state;
}

void CDialerScreen::Draw()
{
    CScreen::Draw();

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            int num = i * 3 + j + 1;
            char buf[16];
            memset(&buf, 0, sizeof(buf));
            sprintf((char*)&buf, "%i", num);

            if(DialerButton(dialerButton, j * dialerButton->Width + 15, 65 + (i * dialerButton->Height) + windowAnimator->Y, buf))
            {
                if(strlen((char*)&number) < 31)
                    strcat((char*)&number, (char*)&buf);
            }
        }
    }

    if(DialerButton(dialerButton, 1 * dialerButton->Width + 15, 65 + (3 * dialerButton->Height) + windowAnimator->Y, "0"))
            {
                if(strlen((char*)&number) < 31)
                    strcat((char*)&number, "0");
            }

    if(DialerButton(dialerButton, 0 * dialerButton->Width + 15, 65 + (3 * dialerButton->Height) + windowAnimator->Y, "C"))
    {
        gLauncher->Modem->Dial((char*)&number);
    }

    gLauncher->Graphics->DrawString(gLauncher->Font, (char*)&number, 10, 48);
}

Обратите внимание на удобство примененного подхода Immediate GUI. Нам понадобился новый элемент интерфейса, который описывает кнопку номеронабирателя? Мы просто реализовываем ещё один метод, который берет за основу стандартную кнопку и дорисовывает к ней текст. Всё крайне просто и понятно, хотя на данный момент слишком захардкожено. :)

image

Звоним!


Пришло время совершить первый звонок с нашей по настоящему кастомной прошивки. Набираем номерок и…

image

Да, всё работает и мы без проблем можем дозвониться :)

Заключение


Конечно же, это далеко не весь функционал, необходимый любому современному смартфону. Здесь много чего еще нужно реализовать хотя бы для соответствия уровню бюджетных кнопочных телефонов: телефонную книгу, поддержку СМС/ММС, мультимедийный функционал с играми. Однако начало уже положено и самая необходимая часть модулей реализована. Этот проект очень занимательный для меня и я горд, что смог не на словах, а на деле показать вам, моим читателям, возможности моддинга совершенно NoName-устройств, без каких либо опознавательных знаков…

Моя задача заключается в том, чтобы показать вам возможности использования старых телефонов не только в потребительских, но и в гиковских DIY-сферах. Судите сами: огромный классный дисплей, емкостной тачскрин, готовый звук, камера — и всё это за каких-то пару сотен рублей. Главное показать людям, как всю эту мощь использовать в своих целях и делать совершенно новые устройства из существующих, а не выбрасывать их на помойку!
Сейчас смартфоны, подобные Fly из этого поста стоят копейки, а портировать на них прошивку можно без каких-либо трудностей. Я очень надеюсь, что после этого поста читатели попытаются сделать что-то своё из старых смартфонов, благо свои наработки я выкладываю на GitHub!



Возможно, захочется почитать и это:


Комментарии (118)


  1. bodyawm Автор
    18.08.2023 08:01
    +32

    Ну что-ж друзья, думаю этим материалам я показал вам, как можно на практике юзать смартфоны прошлых лет в качестве одноплатников. Могу и полноценный материал с мостом URAT -> GPIO написать. Интересует такое?

    В этом материале я собрал довольно много достаточно профильной информации - начиная от работы с графикой, заканчивая работой с модемом (пусть и простенькой). Надеюсь вам не только было интересно читать эту статью, но и познавательно :)


    1. bodyawm Автор
      18.08.2023 08:01
      +5

      @dlinyjА как тебе такое применение? :) Я же говорил, что у девайсов есть перспективы


      1. Rigidus
        18.08.2023 08:01
        +5

        Отличная статья! Сразу захотелось найти такой телефон и поэкспериментировать с ним. Следующая статья должна быть "получаем доступ к GPIO" :)


    1. bodyawm Автор
      18.08.2023 08:01
      +4

      @jpegqsна кнопарях в целом такое тоже можно провернуть, почти на всех кнопках, что я видел - уарт был в открытой доступности.


      1. strvv
        18.08.2023 08:01
        +1

        а на кнопочных "дигмах" и прочих клонах 1100 нокий — там же не линукс, а какое-то другое ядро, я забыл, народ ими долго запиливался.


        1. bodyawm Автор
          18.08.2023 08:01
          +1

          Я не совсем про это. В мобилки на медиатеках и спредтрумах есть DL-режим с возможностью запуцскать произвольный код и есть даташит на чипсет с списком регистров. Поэтому

          SC6531E datasheet (datasheetspdf.com)

          На SciPhone на базе MT62xx (именно на нем базируются современные кнопочники) портировали Linux:

          SciphoneDreamG2 - OsmocomBB - Open Source Mobile Communications


          1. jpegqs
            18.08.2023 08:01

            Самые доступные кнопочные звонилки Медиатека, что сейчас можно купить, конкуренты SC6531E - это MT6261, для предшественника MT6260 есть проект Fernly. Линукс на таких кнопочных не запустить, памяти всего 4Мб, 8Мб у чуть более дорогих, только RTOS влезет.


            Есть кнопочные на MocorOS (мод Android 4.4), там памяти уже достаточно, но они стоят дороже, и найти их сложно. За те же деньги можно дешевый смартфон купить с лучшими характеристиками. На гитхабе можно найти исходники ядра Андроид для некоторых чипов дешевых смартфонов.


            1. bodyawm Автор
              18.08.2023 08:01

              На 4мб старый линух кое-как крутится судя по всему, но остается вопрос с MMU (uclinux точно заведется и будет работать хорошо). Про мокор я уже писал и их я моддил


    1. strvv
      18.08.2023 08:01
      +1

      а если использовать графические библиотеки тех времён, тот же qt1.44, qt2, qt3.3.8? по мере нарастания функционала и у них есть baremetal реализации, напрямую с фреймбуфером, а так и простая lvgl есть, чтобы велосипед не мучать.


    1. Rodik1989
      18.08.2023 08:01

      Да, вполне можно юзать. Вижу мало смысла в использовании не Android на Android железке.

      Скажу, что теме уже Декада и у меня до сих пор есть Samsung S3 на этой прошивке как мини сервер)

      Вот современный аналог ArchiDroid очень интересует под более новое железо (тот же S7 Edge и новее) и тут уже можно сибирать донаты на такое)


    1. Weron2
      18.08.2023 08:01
      +2

      Как насчет прошивка home assitant? Или просто нарисовать виджет выключатель и им управлять умной лампой? Или сервер телеграм, хотя как я понимаю с доступом извне будут проблемы и потому любой такой сервак не имеет особого смысла. Но вообще отличная статья! Очень круто)


  1. pechkinkorp
    18.08.2023 08:01

    можешь заменить распбери пи/орандж пи используемые для доработки 3д принтеров под прошивку клиппера?


    1. bodyawm Автор
      18.08.2023 08:01

      Теоретически возможно.


    1. TheRaven
      18.08.2023 08:01

      Если не хочется покупать апельсина под клиппер, то лучше не заморачиваться полумёртвыми смартфонами, а взять андроидную тв-приставку и перешить.
      Там и БП и корпус и нормальные USB сразу.



      1. N-Cube
        18.08.2023 08:01

        Есть же Raspberry Pi Zero 2 W - и не дорого и хватает для клиппера.


        1. TheRaven
          18.08.2023 08:01

          На алихе она 7к голая, а Orange Pi 3 LTS в комплекте с питальником 4к. При этом апельсин эту зеро по характеристикам превосходит капитально. Опять же 8GB EMMC прямо на плате позволяют не париться по поводу изнашивающихся медленных флешек.


          Не вижу смысла покупать зеро 2w.


          1. Phoenix_free
            18.08.2023 08:01
            +2

            В Турции есть онлайн магазин samm market. zero2w купил там за 1.8к, буквально месяц назад.


          1. N-Cube
            18.08.2023 08:01

            15$ платка стоит: https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/
            Вот и в стороннем магазине в Британии столько же за вычетом НДС: https://shop.pimoroni.com/products/raspberry-pi-zero-2-w?variant=39493046075475 Так что просто ищите по разумной цене там, где вам удобно купить.


    1. nbkgroup
      18.08.2023 08:01

      Лучше сразу купить Bigtreetech CB1 в конструктиве RPi CM4. Он нативно поддерживается в Armbian.


  1. ivankudryavtsev
    18.08.2023 08:01
    +32

    Жаль что и круто и наркоман поставить нельзя :)


    1. bodyawm Автор
      18.08.2023 08:01
      +5

      Ну куда-ж без наркомании в DIY :)


      1. strvv
        18.08.2023 08:01
        +3

        как раз и сам diy даёт такой приход и драйв, то зачем все эти психоактивные вещества?!?


  1. werpo
    18.08.2023 08:01
    +4

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


    1. bodyawm Автор
      18.08.2023 08:01
      +1

      Теоретически возможно, практически - едва ли, т.к исходники Audio HAL я видел ток для медиатека.


  1. onekawdalg
    18.08.2023 08:01
    +2

    Так, думаю, и появилась Rosa Mobile)


  1. PecarVacun
    18.08.2023 08:01
    +2

    очень круто! но в голове постоянно вопросы: - а какое практическое применение можно найти этому безусловно полезному занятию.
    Пока не придумал. Скорее всего, меня ограничивает узость сознания и вошедшее в привычку потреблятство.


    1. bodyawm Автор
      18.08.2023 08:01
      +2

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


      1. NickDoom
        18.08.2023 08:01
        +4

        А если это дорастёт до полноразмерного форка типа Цианогена — можно не мелочиться и запилить экосистему на базе клона Баунтисорса. То есть магазин приложений сугубо опенсорсный, но можно «купить» продолжение разработки в том или ином направлении, по своему заказу. Ну, или дописать желаемое и пополнить таким образом счёт.


      1. olku
        18.08.2023 08:01
        +2

        Железный мессенжер с шифрованием?


    1. MaFrance351
      18.08.2023 08:01
      +2

      После упоминания UART'а на ум приходит какая-нибудь панель управления умным домом или аналогичные девайсы в том же духе и стиле.


      STM32 и дисплей такой диагонали и разрешения стоят конских денег, экземпляры от фирм вроде Nextion ещё дороже.
      А тут можно получить большой экран и сравнительно мощное железо, и со всем этим даже начинающему не жалко экспериментировать, так как новый девайс взамен укокошенного можно купить на Лохито по цене бутылки колы с пачкой чипсов. Дешевле даже самого простенького одноплатника и экранчика к нему.
      Ну, это я так.


      1. sim31r
        18.08.2023 08:01
        +1

        STM32 дает доступ к каждому пину из сотни имеющихся на борту, стоит от 0.5 до 15$ в зависимости от модели. Дисплей TFT на 3.5 дюйма с резистивным экраном стоит 10$ с доставкой, позволяет обновлять с RPi экран на 50 FPS например, вполне отзывчивый.

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


        1. bodyawm Автор
          18.08.2023 08:01
          +2

          С стмкой сравнения некорректны. И даже с RPi Zero: медиатек ощутимо мощнее.


  1. Zara6502
    18.08.2023 08:01
    +9

    Несомненно проект достойный, но - отсутствует повторяемость, а это всегда убивает любой проект. В одного можно еще лет 10 изобретать колесо типа BolgenOS с понятным результатом.

    смастерить игровую консоль, фоторамку с часами и погодой, сервер, портативный плеер, одноплатник

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

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

    2. фоторамка - нужен набор виджетов, где можно подключать погоду, часы, сообщения, календарь, откуда они появятся?

    3. сервер - сервер чего? кто будет портировать на вашу систему например apache, php и т.п.?

    4. портативный плеер - ну допустим какой-то wav вы сможете играть, но интерес будет в mp3, ogg, flac (а у меня больше интереса к чиптюновым форматам), как их воспроизводить?

    5. одноплатник - он бесполезен без софта и готовых библиотек


    1. bodyawm Автор
      18.08.2023 08:01
      +14

      Этот подход предназначен для людей, которые имеют некоторые навыки программирования. Для любителей купить и собрать по туториалам - есть raspberry pi.

      но и эмуляторы писать? а если без эмуляторов, то кто под него будет игры писать?

      Зачем? В сети есть куча эмуляторов, в которых достаточно портировать только HAL под свою платформу. Фактически, можно просто портировать сразу SDL1.2, под который уже есть куча эмуляторов - от атари, до пс1 (привет Dingoo A320). Про n64 и выше мы не говорим - далеко не каждый смартфон их потянте

      будет ли аппаратное ускорение видеочипа

      Зачем вам GLES в эмуляторе 8-16битки? :) Эмуляторы PPU-консолей вручную подготавливают уже готовый кадр, который потом при необходимости перекодируется в нужный пиксельформат и отправляется на контроллер дисплея (который уже реализован в виде /dev/fb). Даже пс1 принято эмулировать в софте, т.к выше точность эмуляции.

      где можно подключать погоду, часы, сообщения, календарь, откуда они появятся?

      Вы так говорите, будто с уже имеющимся Wi-Fi, 2G (через SIM800) и RTC сложно реализовать часы и календарь.

      кто будет портировать на вашу систему например apache, php и т.п.?

      Так под bionic есть порты и apache, и php, и gcc, и fpc :)

      но интерес будет в mp3, ogg, flac (а у меня больше интереса к чиптюновым форматам), как их воспроизводить?

      С добрым утром. vorbis бесплатный и открытый, открытые миниатюрные декодеры mp3 тоже существуют, для того, чтобы был смысл в FLAC, нужен хороший аудиотракт - такое есть не в каждом смартфоне.

      одноплатник - он бесполезен без софта и готовых библиотек

      На этом спор можно было и заканчивать. Варианты применения железа не ограничиваются тем, что кто-то уже что-то сделал за вас :) Материал по очевидным причинам гиковский.


      1. iShrimp
        18.08.2023 08:01
        +1

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


        1. bodyawm Автор
          18.08.2023 08:01

          Это правда. Причем АКБ можно любую подключить, если смартфон стартует от + и -


      1. Firsto
        18.08.2023 08:01

        для людей, которые имеют некоторые навыки программирования

        А вы ещё и в железе разбираетесь на таком уровне, где всему этому научились?:)


        1. bodyawm Автор
          18.08.2023 08:01
          +3

          Как-то сам. Скучно становится - хоп, читаю схему на устройство. Хоп, открыл даташит на интересующий чип. И вот так изучил :)


      1. Zara6502
        18.08.2023 08:01
        -2

        Этот подход предназначен для людей, которые имеют некоторые навыки программирования

        причем тут навыки программирования? я пользуюсь С (платформы MOS 6502, 8088, i386, AtMega), C# (Windows, Linux), ASM (6502, 8088, 80386), Java (Web) и не вижу никакой связи между тем что делаете вы и что делаю я.

        Для любителей купить и собрать по туториалам - есть raspberry pi

        Не ошибусь если скажу что вы тоже всё делаете по туториалам, только по другим.

        Зачем? В сети есть куча эмуляторов, в которых достаточно портировать только HAL под свою платформу. Фактически, можно просто портировать сразу SDL1.2

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

        Зачем вам GLES в эмуляторе 8-16битки?

        может потому что я ими пользуюсь и оно там используется?

        Даже пс1 принято эмулировать в софте, т.к выше точность эмуляции.

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

        Вы так говорите, будто с уже имеющимся Wi-Fi, 2G (через SIM800) и RTC сложно реализовать часы и календарь

        я правильно понимаю вашу логику, что если кто-то в 12 лет катался на тракторе Беларусь (папа дал порулить в поле), то он сразу же знает как чинить турбину на Т-82?

        Так под bionic есть порты и apache, и php, и gcc, и fpc :)

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

        С добрым утром

        ну собственно остальное написанное обсуждать нет смысла потому что вы ввели читателей в заблуждение.

        Материал по очевидным причинам гиковский

        вы не ранжировали материал по степени гиковости, сложность статьи указана средняя.

        ---

        ладно, будем считать что я не понял что написано в статье.


        1. bodyawm Автор
          18.08.2023 08:01
          +3

          Не ошибусь если скажу что вы тоже всё делаете по туториалам, только по другим.

          Я практически с самой юности, с самого малочку пытался программировать игры на самом низком уровне - начиная с рендереров, заканчивая выводом PCM-звука. И я смотрел не туториалы, а читал пейперы от вендоров гпу и спеки огл. Первый раз я по настоящему понял, как работает пайплайн на гпу из спеки на огл, а не из редбука, и тем более не с learnopengl. И так практически во всех областях.

          Может такой крутой дядька, программер графики, как Тимур XProger тоже всё по туториалам делает, только потому что 20 лет назад смотрел условные туторы Neh? :)


          1. Zara6502
            18.08.2023 08:01
            -1

            Я практически с самой юности, с самого малочку пытался программировать игры на самом низком уровне - начиная с рендереров, заканчивая выводом PCM-звука

            Ну ок.

            И я смотрел не туториалы, а читал пейперы от вендоров гпу и спеки огл

            Возможно вы неправильно понимаете слово "tutorial", это не серия книг "рендер для чайников", это бумага в которой что-то написано о чем либо, а вот для кого она написано обычно указано в самом руководстве. Бывают руководства пользователя, администратора, программиста, инженера и т.п. Все эти бумажки кто-то знающий тему пишет для тех, кто тему не знает, но прочитав - узнает. Очевидно, если вы не читали такие руководства, то и знаний у вас нет. И нет никакой связи при этом с программированием.

            Спеки или спецификации - это просто описательный документ. Если вы что-то понимаете читая спеки, то вы точно ранее читали документы объясняющие и используемую терминологию и технологии. Невозможно взять например китайский иероглиф, смотреть на него 20 лет и вдруг осознать кто он означает какое-то слово.

            Так что никаких чудес нет.

            Первый раз я по настоящему понял, как работает пайплайн на гпу из спеки на огл, а не из редбука, и тем более не с learnopengl. И так практически во всех областях.

            И о чём это должно говорить? Что вам понятнее руководства для одних специалистов, но непонятны для других? Оно у всех так.

            Может такой крутой дядька, программер графики, как Тимур XProger тоже всё по туториалам делает

            Очевидно, иначе откуда знаниям взяться? Нет, безусловно вы можете ковыряться с железкой и найти например инженерные функции, которые есть только в закрытых спеках, как те же MOS 6502 инструкции, которые числятся недокументированными. Это полученные знания в ходе экспериментов. Я где-то против такого?

            Короче меня последнее время забавляют ваши оппозитные комметарии к моим статьям, но вы действительно не совсем улавливаете суть

            Суть не улавливаете вы. У вас нет просто достаточных знаний и понимания вопроса связанного с подачей материала, вы действуете по принципу заметок FIDO, чиркнул, а вы там сами разбирайтесь. Но там хоть разговор был в определенных ветках с такими же как он людьми, а вы пишете просто в Рунете для всех, у вас научпоповский формат, вы НЕ пишете для гиков (ну или считаете их тупыми). Для гиков вы не написали ничего того, что они бы сами не знали (вы думаете никто не в курсе что на телефоне можно запустить родное ядро?). Собственно я когда зашел в тему я именно что хотел прочитать про запуск чего-то своего на старой железке. Но вы посчитали что кликбейт полезнее для количества просмотров (спонсор давит?). И подумали, что если написать небольшой референс про кликбейт, то он нивелирует ваш поступок.


        1. bodyawm Автор
          18.08.2023 08:01
          +4

          Короче меня последнее время забавляют ваши оппозитные комметарии к моим статьям, но вы действительно не совсем улавливаете суть :)


    1. Zuy
      18.08.2023 08:01
      +2

      mp3 и flac декодеры в софте я запускал ещё на маленьком arm микроконтроллере лет 10 назад. Там кода ну килобайт 30 максимум.

      А про все остальное согласен. Интересно и прикольно, но смысла, кроме как поиграться, нет.


    1. Lord_Ahriman
      18.08.2023 08:01
      +5

      еще лет 10 изобретать колесо типа BolgenOS с понятным результатом

      Абсолютно некорректное сравнение. Болгенос не был никаким колесом, а был обычным воровством, когда школьник поменял в Убунте несколько строк названий и пару нескучных обоев, и выдал все это за свою собственную разработку. Там вообще не было никакой разработки и никакого программирования, в отличие от гигантской работы, проделанной автором.

      Раз уж вы хотите сравнений, то корректнее было бы сравнивать с проектами типа Kolibri/Haiku/Menuet.


  1. AWRDev
    18.08.2023 08:01
    +1

    Очень круто, действительно старые телефоны не хочется, да и неинтересно выкидывать просто так.

    Вопрос, может на него ответ где-то был уже, но всё же. Чем это лучше дальше использовать тот дроид, который там и установлен? И насколько легко повторить действия из этой статьи на другом телефоне с таким процессором/другим процессором/на телефоне времен 5/8/10 дроида?


    1. bodyawm Автор
      18.08.2023 08:01
      +7

      Чем это лучше дальше использовать тот дроид, который там и установлен

      Ведро жрет кучу ресурсов и до жути проприетарное под капотом.

      И насколько легко повторить действия из этой статьи на другом телефоне с таким процессором/другим процессором/на телефоне времен 5/8/10 дроида?

      Почему бы не проверить самому? Главное - разлоченный бут.


      1. olku
        18.08.2023 08:01
        +1

        А его можно подменить своей опенсорсной реализацией? На такое дело можно и в краудсорс.


        1. S-trace
          18.08.2023 08:01
          +1

          Можно при желании, но только на тех устройствах где подпись aboot/ABL не проверяется SBL.

          Увы, на многих современных железках его подпись проверяется даже если он разлочен (то есть подпись boot/recovery не проверяется после разлочки, но все загрузчики проверяются всё равно).

          https://github.com/jsr-d10/android_bootable_bootloader_lk - пример кастомного LK для Snapdragon 400 (с загрузочным меню, настройками и возможностью загрузки с сдкарты (в том числе и мультизагрузки)).


      1. Weron2
        18.08.2023 08:01
        +1

        Теперь придется изучать как разлочить бут)

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


        1. bodyawm Автор
          18.08.2023 08:01
          +1

          На стареньких девайсах ничего разлочивать не нужно, особенно на MediaTek. Взял и поставил - и никто не мешает. Это одна из причин популярности моддинга на MediaTek :)


        1. S-trace
          18.08.2023 08:01
          +2

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

          Если у вас проблемы начинаются на стадии разлочки бутлоадера - похоже, эта тема не для вас.

          А вообще - готовый рецепт имеется практически для любой модели/семейства/производителя, надо только поискать (привет 4pda/xda). Не разлачиваются нормальным путём обычно всякие операторские аппараты. Но порой и на них находят управу (от эксплойта в boot.img/recovery.img и патчинга aboot (да, были такие забавные модели у LG которые не проверяли подпись aboot, но проверяли подпись boot) до использования всякого спецсофта для низкоуровневой работы с процом).


  1. nbkgroup
    18.08.2023 08:01
    +12

    Это очень круто и действительно нужно! Материал практически уникальный в своём роде. Продолжай пилить!

    Это очень круто, но никому не нужно в практическом плане. Потому что нужны повторяемые решения из стандартных компонентов, а не штучные решения из случайных компонентов, найденных на свалке.

    В мире постапокалипсиса это зашло бы, да. Но там не было бы интернета и доступных архивов софта на все случаи жизни.


    1. bodyawm Автор
      18.08.2023 08:01
      +1

      Решение более чем повторяемое. Прошивка не только на одном девайсе работает и без проблем должна работать в том числе и на свежих декспах из днса по полторы тыщи рублей


      1. nbkgroup
        18.08.2023 08:01
        -5

        Она ценна исключительно как пример для самообразования и профессионального роста, и в основном для автора. У решения нулевая, если не отрицательная потребительная стоимость. Ребенок сейчас хочет топ, давать такое старику — издевательство, а обычный средний пользователь не будет такое использовать ввиду слабой надежности, документированности и ремонтопригодности.

        Вашу бы энергию да на пользу обществу, а не на игру в бирюльки.


        1. Moog_Prodigy
          18.08.2023 08:01
          +10

          Подобного рода проекты - не для детей, стариков и прочих домохозяек. В первую очередь для гиков. Разумеется, ни о какой массовости речи не идет, как и о "давайте всех на мою прошивку переведем". Статья исключительно о том, как получить из старого девайса нечто такое, что за такие смешные деньги не купить. Например HMI (панели оператора) даже на известном китайском сайте стоят совершенно не смешные деньги с совершенно смешным функционалом. На той основе, что предложил автор, можно наклепать эти панельки себе куда угодно, и не ломать себе глаза на мелких экранчиках типа 128х50 размером сантиметр на полтора (условно). А по сути телефон это компуктер и для DIY компуктер довольно нафаршированный. И даже если у него нет GPIO, всегда можно его туда придумать, я более чем уверен). Нет, можно конечно использовать одноплатник, но цена несравнима, это прям пропасть глубиной в Марианскую впадину.


          1. bodyawm Автор
            18.08.2023 08:01

            GPIO можно вывести через внешний МК, а между ними мост через UART-проложить.


          1. Kudriavyi
            18.08.2023 08:01
            +10

            Это вообще не смешные деньги. Оценивая трудозатраты мне дешевле будет купить малинку и под неё написать целевую программу. Я всегда вспоминаю сколько стоит мой рабочий день и считаю примерную стоимость исполнения.

            Но с позиций спортивного программирования этот проект достоин уважения!


            1. nbkgroup
              18.08.2023 08:01
              +1

              Автор в силу возраста не понимает, что время — это самый ценный и невосполнимый ресурс. И сколько не пиши и не говори об этом, человек будет глух, пока внезапно не осознает, что его время ограничено. Кто-то ощущает это, беря ипотеку, кому-то сообщают онкологический диагноз, а до кого-то доходит в военкомате.

              Регулярное чтение данной серии публикаций вызывает у меня ощущение, что человек прикуривает одну за другой сигареты из нераспечатанной пачки "Ту-134" 1980 года, купленной на блошином рынке, от стадолларовых купюр.

              Смотреть на это прожигание жизни и таланта конечно прикольно, но и вызывает испанский стыд за столь жалкое использование знаний и способностей.


              1. bodyawm Автор
                18.08.2023 08:01
                +1

                Во мне нравится это псевдоменторство, вам то какое дело, кто и как использует своё время? Я по жизни балдею, хорошо зарабатываю и нахожу время на всё, что мне интересно - тачки, кодинг, копание в железе. Так что я живу идеально можно считать :)


                1. nbkgroup
                  18.08.2023 08:01
                  -2

                  Это не псевдоменторство, а скорее испанский стыд.

                  Вот есть же у вас действительно ценная статья про использование дисплеев. Возможно, стоит думать в таком направлении?


                  1. bodyawm Автор
                    18.08.2023 08:01
                    +3

                    Ну а чем статья о использовании старых смартфонов в качестве одноплатников, сразу с готовыми дисплеями, тачскринами и звуком не ценная? :)


              1. aml
                18.08.2023 08:01
                +2

                Эх вы, горе-комментаторы. Настоящие, самые глубокие знания чего бы то ни было получаются именно таким образом. Ценность - не в фоторамке, а в том, что автор будет возглавлять крутейшие R&D и инженерные лаборатории, а его разработки будут делать мировые новости. Никаким чтением документации, инструкций и учебников этого не получишь.


          1. sim31r
            18.08.2023 08:01

            Специально полез смотреть на экраны, 3.5" TFT 400*240, резистивный сенсорный экран стоит 10$ из них треть это доставка. В отзывах пишут что с RPi 50 FPS получают. Телефон круто использовать, но кроме того что пишут в соседних комментариях есть еще проблема - неповторяемость конструкции. Даже вот автор отладит конструкцию, но повторить её в 5 экземплярах не сможет. Телефоны могут быть с другой ревизией и код придется адаптировать под каждый телефон заново. С Orange Pi такая же проблема была, разработчики просто сменили чип и все предыдущие наработки нужно было переписывать под новое железо. RPi в этом плане намного стабильнее, поддерживаются старые версии. А микроконтроллеры еще более консервативные, в продаже до сих пор есть микроконтроллеры 90х годов или какой-нибудь Z80.

            телефон это компуктер и для DIY компуктер довольно нафаршированный

            Только недоступный на низком уровне. Нет гребенки пинов например, как у ESP32 хотя бы.


            1. bodyawm Автор
              18.08.2023 08:01

              Даже вот автор отладит конструкцию, но повторить её в 5 экземплярах не сможет

              Смогу. И на самых разных флаях смогу, даже на разных чипсетах!

              Телефоны могут быть с другой ревизией и код придется адаптировать под каждый телефон заново

              Нормальные вендоры всегда указывают HW Version/SW Version. А во вторых, в мобилках хардварные ревизии - обычно смена различных eMMC (у мтк есть зависимость от CID флэши) и иногда модулей камеры. В этом и прелесть линуха - что фактически мне предоставляют единый интерфейс для общения с периферией и я могу без проблем портировать прошивку между разными устройствами.

              Upd: Мне не нужно лезть в драйвер фреймбуфера, этим занимается линух.

              Только недоступный на низком уровне. Нет гребенки пинов например, как у ESP32 хотя бы.

              Можно самому мост изготовить без проблем. Ну и если так посмотреть, у OPi тоже нормальной гребенки нет, лишь пару GPIO, а остальные - SPI, I2C, питальники и.т.п. И с большинства мобилок тоже можно взять как минимум i2c.


              1. nbkgroup
                18.08.2023 08:01
                +1

                Есть старая максима гласящая, что умный человек блестяще выходит из таких ситуаций, в которые мудрый никогда не попадает.


      1. Rigidus
        18.08.2023 08:01
        +1

        Я бы в гитхаб-репо добавил список совместимых с проектом телефонов, чисто для того чтобы было проще искать


        1. bodyawm Автор
          18.08.2023 08:01

          Хорошо, я назаказывал кучу флаев прошлых лет, предстоит на них проверить)


      1. NickDoom
        18.08.2023 08:01

        То есть если мне понадобится, допустим, снабдить полсотни рабочих специальными терминалами со складским ПО типа «иди к десятой полке, положи товар N, отсканируй штрих-код» — это решение позволит сэкономить (1500-300)*50 = 60К, но при этом не завязывается на постоянное наличие на вторичном рынке определённой модели телефона, зато отвязывается от поддержки выбранной модели тем же гуглём.

        Экономия, может, и копеечная, а вот второй фактор (берут и перестают ведро поддерживать, и здрасте-дыры) — уже серьёзно.


        1. p07a1330
          18.08.2023 08:01

          Что мешает выдать этим рабочим простенькие телефоны-андроиды, отрубить их от внешней сети и подключить к локалке с вебсервисом сканера?
          Уязвимость не может попасть на телефон, не бывающий в сети
          И для работы хватит браузера/вебвьюшки


        1. sim31r
          18.08.2023 08:01
          +2

          Экономия будет при наличии бесплатного программиста такого уровня.

          не завязывается на постоянное наличие на вторичном рынке определённой модели телефона

          На других моделях или даже ревизиях код может не заработать. Поменяется интерфейс подключения экрана например и придется менять низкоуровневый код.

          отвязывается от поддержки выбранной модели тем же гуглём

          Зато привязываетесь к программисту и человеческому фактору. Он может поставить таймер на разрушение системы, чтобы подстраховаться в плане оплаты и техподдержки.


  1. NickDoom
    18.08.2023 08:01
    +2

    Я, как трижды идеологический сторонник (по экологическим, экономическим и технофильским соображениям), прошу всех обратить внимание на эту идею: https://github.com/NickDoom-IDKFA/OGLOED-Stub

    От простого «А почему бы просто не поднять иксовый сервер на этом самом External Device» оно отличается, как минимум, возможностью запуска с минимальными привилегиями (как у игрушки, а не как у сервера), а как максимум — возможностью запрячь CPU в помощь GPU, если последний не умеет какие-то вычурные операции сам по себе (что имеет прямое отношение к статье — берём фирменное ядро Линуха для данного телефона и вместо ведра на него цепляем оглоеда, который умеет только одну вещь, но зато умеет её предельно эффективно). Ну, и поскольку иксовый сервер остался на клиентской машине, она тоже может во все 16 ядер (или сколько там есть) апгрейдить версию опенгл с доступной до нужной, что сильно повышает полезность старого телефона в качестве внешнего дисплея (если бы мы полностью вынесли иксы на телефон, этого бы мы лишились). Короче, см. диаграмму, на ней всё это есть.

    Хотел было создать на Баунтисорсе мета-ишью «напишите это кто-нибудь» и кинуть пять баксов для затравки, но с платежами там всегда было странно, а сейчас ещё чудесатее :(


    1. kmeaw
      18.08.2023 08:01

      Не очень понятно, почему иксовый сервер работать не будет, а OGLOED - будет. И если у нас уже есть мощная 16-ядерная машина для запуска приложения, а External Device маломощный и отгороженный проприетарной ОС, то почему бы просто не стримить уже готовое видео?


  1. Kasefuchs
    18.08.2023 08:01
    +1

    Читая эту статейку почти каждую минуту вспоминал те самые китайские айфоны 8-летней давности...


    1. bodyawm Автор
      18.08.2023 08:01
      +3

      Да, UI очень похож на них) В первую очередь из-за того, что концептуально используются похожие принципы построения интерфейса - не сглаженные моноширинные шрифты, слизывание интерфейса айфона))


  1. Astroscope
    18.08.2023 08:01
    +1

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

    Хотел проголосовать за "Автор наркоман", имея в виду сделать комплимент, но политкорректно выбрал первый пункт. :)


  1. TimReset
    18.08.2023 08:01
    +2

    >> только ввод и вывод данных из звукового тракта модема происходит через звуковую подсистему Android — к которой доступа у нас нет!

    Не мог бы ты чуть поподробнее рассказать, как это устроено? Я думал что Android поверх Linux работает и использует только то что Linux ему поставит. А вообще есть такие Android смартфоны где можно из Linux доступ к модему получить?


    1. bodyawm Автор
      18.08.2023 08:01
      +8

      Сейчас расскажу:

      Издавна, в Linux есть две звуковые подсистемы - OSS (Open Sound System) и ALSA.

      OSS славится своим простым интерфейсом - фактически, программы могут просто посылать "сырой" PCM звук в /dev/dsp, причем сразу из нескольких каналов (у подсистемы есть микшер) и получать на выходе звук. Да, вот так просто. При необходимости, можно было настроить частоту дискретизации, моно/стерео и.т.п.

      Затем ему на смену пришла ALSA, т.к OSS была проприетарщиной. С этой подсистемой работать немного сложнее - нужна alsalib.

      А в ведре решили плюнуть на все это многообразие и сделали свою звуковую систему поверх всего - прямо как часть Android HAL. А поскольку открывать исходники HAL никто не требует - получаем проприетарщину!


      1. Zuy
        18.08.2023 08:01

        Вау, ну зачем так категорично. Есть audio hal, которые работают поверх ALSA и их исходники открыты.

        Андроид не диктует как надо реализовать audio hal, если есть драйверы звуковой подсистемы которые дают ALSA или OSS, то hal делается поверх них.


        1. bodyawm Автор
          18.08.2023 08:01
          +2

          Это уже от вендора зависит. На 6572/6580 есть /dev/dsp и устройства ALSA, на 6573 - вообще ничего связанного с звуком в /dev/ нет, вероятно, весь звук через HAL. Вся обработка голоса тоже идет через звуковую подсистему андроида :(


          1. Zuy
            18.08.2023 08:01
            +1

            Так я это и имел ввиду, что не Андроид делает по другому, а вендоров так реализуют свое аудио. Самому Андроиду вообще все равно что там ниже HAL.


          1. ectraldo-48
            18.08.2023 08:01
            +3

            у 6573, 6575, 6577 и ещё нескольких звук в андроиде выводится через собственную мткшную подсистему yusu, костыльную настолько, что в андроиде приходится реализовывать фейковую alsa и обвязку для неё с пустыми роутами, конфигами. Драйвер AFE (audio front-end) там написан так, что без слёз не взглянешь. Пару раз садился за это дело, но в конечном счёте так и не смог разобраться, в каком порядке что взаимодействует для вывода звука на 6577. Там ещё и libbessound проприетарный на подхвате. Если хорошенько подумать, то уверен, что реализовать звук можно и без зависимости от андроида, достаточно будет сделать alsa-совместимую прослойку для AFE+YuSu.


            1. bodyawm Автор
              18.08.2023 08:01
              +2

              Благодарю за наводку! На 6572 тоже какой-то фейковый ALSA/OSS, прямой вывод в dsp там ничего не даёт, как и установка volume/mut


      1. lealxe
        18.08.2023 08:01
        +1

        Только OSS не проприетарщина. Просто в новой версии основной реализации там когда-то сделали несовместимую лицензию. А уж API OSS тем более не проприетарщина, и причина его замены - в синдроме NIH. Во FreeBSD вот своя звуковая подсистема, но с API OSS. Потому что было везде и красивое и удобное.


        1. bodyawm Автор
          18.08.2023 08:01

          С удобностью согласен)


          1. kmeaw
            18.08.2023 08:01
            +2

            API OSS перестаёт быть удобным, когда нужно реализовывать не push (приложение заранее подготовило звук и делает write в сторону ядра), а pull (ядро понимает, что железу скоро будет нечего воспроизводить, и просит приложение сгенерировать новые аудиоданные).


      1. allcreater
        18.08.2023 08:01
        +1

        Оу, извините, все равно непонятно, почему же получается проще прикрутить к телефону второй модем, а не добраться до встроенного :'(

        Правильно ли я понимаю, что по сути проблема в том, что для всей звуковой системы телефона просто нужны заковыристые драйвера, которые по-быстрому не написать и в опенсорсе не доступны, или есть какие-то более фундаментальные трудности?

        Извиняюсь, если вопросы глупые, я во внутренностях линухов (и особенно телефонов на нем) не силен, но тема чертовски интересная!


        1. bodyawm Автор
          18.08.2023 08:01

          Правильно ли я понимаю, что по сути проблема в том, что для всей звуковой системы телефона просто нужны заковыристые драйвера, которые по-быстрому не написать и в опенсорсе не доступны, или есть какие-то более фундаментальные трудности?

          Не совсем, но я пока не полностью разобрался в запуске модулей ведра отдельно от самого ведра. GLES хардварный, например, я пока что поднять не смог.


  1. LevOrdabesov
    18.08.2023 08:01

    Как резко поменялся формат статей. Я, конечно, извините, но это не перевод ли, разбавленный повторением описанных в оригинале действий?

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


    1. bodyawm Автор
      18.08.2023 08:01
      +3

      Блин, странная логика конечно, если что-то уникальное и крутое - значит обязательно перевод)) Я давно пропагандирую моддинг устройств в своем блоге:

      https://habr.com/ru/companies/timeweb/articles/726086/

      https://habr.com/ru/companies/timeweb/articles/736438/

      Китайский айфон на чистом Android — совсем бесполезен в 2022? / Хабр (habr.com)

      Обзоры на девайсы пишу под аккаунтом @MDXE1337


      1. LevOrdabesov
        18.08.2023 08:01
        -1

        Нет, не странная. К сожалению, история очень распространённая. Уровень разный, на мой вкус. Есть серьёзная разница между тем, чтобы залить в старое устройство кастомную прошивку и включить там в плеере "Чернобуркв", и тем, чтобы запихать туда голый линукс, нафигачить какую-никакую, но графику, да ещё и возиться с подключением внешнего сим-модуля (пусть даже он и на AT-командах). Если всё своё, то только хорошо, конечно.


      1. MaFrance351
        18.08.2023 08:01
        +1

        Обзоры на девайсы пишу под аккаунтом MDXE1337

        Так это виртуал? Или товарищ твой?


  1. Zuy
    18.08.2023 08:01
    +7

    Както очень уж радикально. Я делал по другому. Грузился в нормальный андроид, но не грузил Zygote. Таким образом получал полноценный Линукс но без Андроид фреймворка. А это значит там были GPU, Audio, HW composer и т.п. ништяки. Т.е. весь HAL можно было использовать напрямую. Т.к. фреймворк Андроида не грузился то все это запускалось за считанные секунды.


  1. titbit
    18.08.2023 08:01
    +4

    Эх, делали же раньше устройства, можно было свои прошивки писать с нуля, а сейчас все заколочено наглухо и надо преодолевать большое число препятствий чтобы хоть что-то там сделать. Можно прямо статьи писать, как приходится реверсить ключи и прочую криптографию чтобы иметь возоможность хотя бы патчить компоненты. Сейчас же в телефонах полный набор: траст-зона, гипервизор, несколько ОС (включая RTOS) работающих одновременно, аппаратные ключи и подписи ну и почти полное отсутствие даже доков, не говоря уж об исходниках. Ну и конечно такой адский труд получается никому особо не нужный, разве что для развлечения, потому что производители последовательно и жестко отбивают желание что-то делать, продолжая закрывать все что только можно.


    1. NickDoom
      18.08.2023 08:01
      +1

      Ну, если не обязательно обладать именно топовым флагманом — проблема решается через коллективный заказ у дядюшки Ляо любой партии любых телефонов любой степени открытости, была бы только схема электрическая принципиальная.

      Состоящая из первой попавшей под руку опенсорсной ARM-платы подходящей мощности и стандартного GSM-модема со стандартным интерфейсом, плюс периферия.


      1. MaFrance351
        18.08.2023 08:01
        +1

        Так можно сразу минимальную партию каких-нибудь у каких-нибудь ODM купить, раз уж так пошло.


        Чуть детальнее про это писал DarkTiger в комментарии к этой статье.


      1. titbit
        18.08.2023 08:01
        +5

        К сожалению это только верхушка айсберга. Дядя Ляо конечно продаст вам партию телефонов с вашим шильдиком и даже с принципиальной схемой, которая не сильно отличается от референса, но основу всего составляет SoC, а условное SDK/DDK для них (возьмем любого из тройки MediaTek, Qualcomm, Samsung для примера) - очень закрытое и у вас не будет даже исходников многих компонентов, и в этом будет основная проблема: вы даже произвольную версию ядра линукс не поставите на свой телефон. Никаких исходников RTOS, гипервизора, видеоускорителя вы не получите вообще. От модема и трастзоны - частично, зависит от заплаченных денег (могут вообще не дать). У вас даже ключа не будет для подписи некоторых компонентов прошивки, вам их выдадут в бинарном виде и выбросить их нельзя, потому что на них многое завязано. Понятно что возможности глубоко лезть в потроха у вас просто не будет, либо придется отключать целые узлы системы, если это вообще возможно. И да, все это добро выдается по подписке, либо на конкретную версию (диапазон) андроида, и версию выбираете не вы.

        Проблема в том, что 99% "вторичных" производителей (которые сидят на готовых решениях дяди Ляо) телефонов устраивает такая практика - они не лезут в систему вообще, а кастомизация заключается в настройке "нескучных обоев" и региональных ограничениях в софте и настройках. И видя это производители SoC перестают выдавать даже документацию на отдельные компоненты - зачем, если никому не нужно в итоге. Сравните SDK пятилетней давности и сегодняшний например.


        1. action52champion
          18.08.2023 08:01
          +1

          Вот с этого замечательного комментария должны начинаться все статьи по портированию линуксов на андройдодевайсы и кнопочники на дешевых SoC. Потому что многие люди даже тут не понимают всю глубину анальной огороженности телефонных SoC. И соответственно всю бесперспективность попыток что-то туда полноценно портировать.


  1. Ole
    18.08.2023 08:01
    +2

    Спасибо, познавательно. Читал с большим интересом)


  1. ciuafm
    18.08.2023 08:01
    +1

    Спасибо за статью, вся серия интересная. Можно ли разжевать поподробнее варианты как можно внедриться в телефон или планшет без экрана (с полностью разбитым). Т.е. известно что планшет загружается, но ничего не видно. Есть ли какие то образы для загрузки с СД карты, етс?


    1. bodyawm Автор
      18.08.2023 08:01

      Образоы есть ток если у вас чипсет AllWinner. Можно включить adb, если у вас относительно старое устрйоство - ищем прошивку на него, выдергивает boot.img, распаковываем с помощью mtkimgtools, меняем в default.prop ro.secure=0, ro.debuggable=1, перезапаковываем и заливаем на устройство родным флэшером. После этого, вам станет доступен терминал - adb.


      1. S-trace
        18.08.2023 08:01

        Добавлю, что если прошивки нет, но смарт на MTK - прошивку можно вычитать прямо из него (через SP Flash Tool и функцию readback). Главное скаттер (txtшка со списком разделов с их адресами началами и размерами) потом правильный сделать перед тем как пропатченный boot.img шить. Я так делал. А потом уже (имея adb) можно запустить scrcpy (если Android 5.0+) и получить GUI смарта в окошке на компе с возможностью управления.


        1. bodyawm Автор
          18.08.2023 08:01

          Даже скаттер не нужен) Сервисный софт умеет дампить напрямую без него (Miracle Thunder).


          1. S-trace
            18.08.2023 08:01

            Да это понятно что для дампа скаттер не нужен, я и через SP Flash Tool дампил с фейковым скаттером (в котором один раздел "на все деньги"), а вот зашить обратно пропатченный boot.img без скаттера хотя бы с этим самым boot уже не получится, имхо.


            1. bodyawm Автор
              18.08.2023 08:01

              Write memory :) ANDROID в HEX-редакторе поискать.


  1. checkpoint
    18.08.2023 08:01
    +2

    Автор, продолжайте развивать тему. Причесывайте и выкладывай код на Github. Может быть когда нибудь Ваш проект составит конкуренцию SailfishOS и иным Linux-based мобильным операционкам.


    1. bodyawm Автор
      18.08.2023 08:01

      Код уже есть на гитхабе, но причесать стоит)


  1. ectraldo-48
    18.08.2023 08:01
    +3

    Однако никто не мешает в будущем просто прошить раздел recovery вместо boot

    Вот здесь хочется добавить: кое-что помешать может - это зависит от используемого инструментария для создания конечного .img образа. Всё дело в заголовках.

    В структуре образа boot/recovery у старых мтк каждая часть имеет свой дополнительный заголовок. Ядро всегда имеет заголовок KERNEL. Рамдиск - ROOTFS либо RECOVERY, как раз в зависимости от раздела, с которого U-Boot производит загрузку.

    Когда я пытался реализовать поддержку mt6577 в mainline-ядре, я задокументировал (вырвиглазно) этот момент, т.к. пару раз наступал на грабли нерабочего запуска. В моём случае дополнительно надо было делать рамдиск-обманку для удовлетворения требований U-Boot'a, тогда как на самом деле абсолютно всё необходимое склеивалось в состав единого zImage.

    Вариантов решения проблемы - масса. Например, можно пропатчить образ U-Boot (недостаток - если устройство использует подписанную прошивку с файлами *-sign.img, то флештулом надо будет шиться через меню Write Memory вместо Download). Можно пропатчить U-Boot на уровне исходников, но, судя по отзывам с 4пда, начинается лютый карнавал при попытке его собрать. Самый очевидный вариант - банально прописать правильные заголовки для mkimage в своём Makefile или полностью отдать на откуп эту проблему "кухне", если она используется.


  1. Andy_Big
    18.08.2023 08:01
    +2

    Зашел только из-за заголовка "написал свою прошивку с нуля" и в самом же начале увидел резкий разворот на 180° - "с нуля писать не буду" :(


  1. DeskundigeICT
    18.08.2023 08:01
    +2

    Зато это pet-project, который автор может показать его как приложение к резюме и мотивационному письму в какой-нибудь imec в Лёвене. И его возьмут на работу, потому что такие специалисты на вес золото.


  1. leon76
    18.08.2023 08:01

    А модем и wifi/BT на самом Mediatek доступны? СМС и дата например работают?


    1. bodyawm Автор
      18.08.2023 08:01
      +1

      С датой пока не разобрался, СМС работают, звонки тоже (без звука).

      WiFi и BT есть, но с ними работать сложнее.


      1. leon76
        18.08.2023 08:01
        +1

        SMS уже неплохо, получается стандартные АТ команды можно слать в модем?

        По WiFi и BT интересно получится ли их завести, тот же вопрос про GPS кстати, если беспроводные интерфейсы заработают то сильно больше вариантов использования появляется.


        1. bodyawm Автор
          18.08.2023 08:01

          Можно, но только предварительно послав прошивку на модем и настроив CCCI. WiFi точно можно, GPS теоретически.


  1. grvelvet
    18.08.2023 08:01
    +1

    Походу автор запилил свою МТК ОС на ядре линупса.


  1. Passter
    18.08.2023 08:01

    Мало что понятно, но ооочень интересно! +)

    Отдельное спасибо за "коприовать сканлайнами прямо в задний буфер"

    -что бы это не означало +))


  1. Kroligoff
    18.08.2023 08:01

    Примерно тоже самое делали 20лет назад на Siemens SX1, портировали линух + гуи

    Там тоже модем внешний.

    Возможно стоит взять уже готовое решение

    • FLNX GUI toolkit (this is a nano-x version of FLTK).

    • Nano-X small X-server

    • customized Nanowm window manager

    • TPL serialization library (http://tpl.sourceforge.net)

    • gsmmuxd - GSM multiplexing daemon

    • Tiny message bus system - TBUS

    Оболочка Qtopia выглядела так:


    1. bodyawm Автор
      18.08.2023 08:01

      Иксы на мобилки я точно не потащу)