Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nintendo Switch OLED — снятие третьего уровня защиты панели

Short version (EN): first documented unlock of level 3 register protection on the Nintendo Switch OLED panel (Samsung AMS699VC01), plus a full dump of its vendor registers. The community has only ever used levels 1–2. Includes the exact packet, the one place where it works, a working hekate patch, and the resulting register map.


Что здесь

Панель Nintendo Switch OLED — Samsung AMS699VC01. Её регистры закрыты трёхуровневой защитой. Сообщество, включая hekate, использует только первые два уровня.

Здесь — снятие третьего, подтверждённое обратным чтением, и карта сорока вендорских регистров за ним.

Замок 0xE2

Читается целиком, десять байт — пять групп по 16 бит:

5A 5A | A5 A5 | A5 A5 | A5 00 | A5 00
ур.1    ур.2    ур.3    ?       ?

5A — открыто, A5 — закрыто. Первый уровень открыт заводом, второй и третий закрыты.

Чем открывается

hekate шлёт пятибайтный пакет, и он достаёт только до второго уровня:

DSI_WR_DATA = 0x539;        тип 0x39 (DCS long write), счётчик 5 байт
DSI_WR_DATA = 0x5A5A5AE2;   E2 5A 5A 5A
DSI_WR_DATA = 0x5A;         пятый байт
DSI_TRIGGER = DSI_TRIGGER_HOST;

Ей больше и не надо — ELVSS живёт на втором уровне.

Для третьего нужно шесть параметров, то есть пакет из семи байт:

DSI_WR_DATA = 0x739;        счётчик 7 байт
DSI_WR_DATA = 0x5A5A5AE2;   E2 5A 5A 5A
DSI_WR_DATA = 0x005A5A5A;   5A 5A 5A + паддинг
DSI_TRIGGER = DSI_TRIGGER_HOST;

Результат чтения после записи:

до:    5A 5A | A5 A5 | A5 A5 | A5 00 | A5 00
после: 5A 5A | 5A 5A | 5A 5A | A5 00 | A5 00

Возврат — тот же пакет с A5 вместо последних 5A.

Где это работает, и только там

Внутри display_init() загрузчика. Больше нигде.

Причина: под HOS бит DSI_CONTROL.HOST_ENABLE сброшен до того, как любой сисмодуль получает управление. Проверено на нулевой секунде до инициализации служб, на 11-й, на 23-й и непрерывной слежкой 30 секунд — он закрыт всегда.

Из меню загрузчика тоже не выйдет: там уже идёт видеопоток, и host-пакеты не доходят.

Единственное окно — момент, когда загрузчик поднимает дисплей и сам разговаривает с панелью.

Что за третьим уровнем

40 регистров с настоящим содержимым из 176 опрошенных. Полный дамп — data/panel_dump.txt.

Ключевое:

регистр содержимое
0x04 50 9B 20 — идентификатор, декодируется в 0x2050
0xB1 питание и ELVSS
0xB5, 0xB7, 0xB9 таблицы гаммы, RGB-триплеты
0xBB таблица из 11 записей с шагом 10
0xBC, 0xBF ASCII-строки прошивки панели
0xC8, 0xC9 кривые по 4-байтным группам
0xE2 сам замок

Регистров кадровой развёртки там НЕТ. 0xF2, 0x60, 0x68 — те, что есть у родственного семейства S6E3FC3 — отдают дежурную однобайтовую отписку даже при открытом третьем уровне.

Подтверждается драйвером родственного контроллера в ядре Linux (panel-samsung-s6e3fc2x01.c): там ни одной команды частоты кадров, режим один, тайминги задаёт хост.

Как повторить

Сборка

git clone https://github.com/CTCaer/hekate
cd hekate
git apply /путь/к/patch/panel_dump.patch
cp /путь/к/src/panel_dump.* bdk/display/
cp /путь/к/tools/lzpy.py tools/
make

tools/lzpy.py — замена host-утилит lz77 и bin2c на Python. Нужна, если на машине нет родного компилятора: формат потока взят из tools/lz/lz.c, обратимость проверена round-trip'ом. Если gcc есть, файл не нужен, а правки Makefile из патча можно откатить.

Снятие дампа

  1. Положить output/hekate.bin на карту как payload.bin.
  2. Выключить консоль полностью.
  3. Включить, удерживая VOL+. Дамп снимается молча, до появления картинки, около секунды.
  4. В меню: Console Info → Panel dump (или Tools → Panel dump).
  5. Отчёт ляжет в корень карты как panel_dump.txt.

Без VOL+ в панель не уходит ни одного пакета.

Что внутри опыта

  • проверка идентификатора до первого пакета: на чужой панели не отправляется ничего;
  • замок возвращается на любом пути выхода — между снятием и возвратом в коде нет ни одного return;
  • обход ограничен бюджетом времени, чтобы молчащая панель не дала минуты чёрного экрана;
  • дежурная отписка отделяется от содержимого по гистограмме: байт считается отпиской, только если встретился не меньше восьми раз.

Грабли, на которых легко потерять неделю

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

Длина ответа. Разбирать надо по типу ответного пакета, а не по тому, сколько байт запросили: 0x21 короткий 1 байт, 0x22 короткий 2, 0x1A/0x1C длинный со счётчиком, 0x02 отчёт об ошибке, 0x84 подтверждение без данных. Запрос 10 байт при коротком ответе легко прочитать как ноль.

Спящая панель. Настройка частоты врёт: докладывала 60 Гц, когда развёртка шла 15 и 34. Судить можно только по замеру кадра.

Износ блока DSI. Порядка 30–50 чтений за загрузку, дальше очередь залипает и чтения идут сплошным FFFFFFFF. Необратимо в пределах загрузки.

DSI_TRIGGER не диагностика. Бит взведён в покое, до всякого пакета. Счётчик очереди передачи общий с видеопотоком и тоже ничего не говорит. Единственное доказательство доставки — ответ панели.


Про частоту кадров выше 60 Гц

Замок вскрывали ради этого. Ответ: регистра частоты у панели нет, а потолок лежит в её строчном драйвере.

Проверено десять направлений:

направление итог
подъём пиксельного клока (PLLD) 66 Гц — срыв
пересчёт таймингов D-PHY все параметры в допуске, срыв остаётся
преэмфазис и сила драйвера площадок DSI эффект есть, стену не двигает
ужимание горизонтального гашения срыв тот же при стоковой скорости линии
сохранение времени вертикального гашения без изменений
холодный старт на 90 / 70 / 67.7 Гц чёрный экран / зелень
порядок калибровки MIPI_CAL отрабатывает верно, после смены клока
питание и гамма (ELVSS) от яркости не зависит
заморозка D-PHY без нашего пересчёта хуже
голодание дисплейного контроллера флагов недобора нет (140 000 опросов за 50 мс)

Что общего у всех отказов

Единственная величина, которая росла при всех способах — строк в секунду:

60 Гц:  78 000 строк/с  ->  12.82 мкс на строку   чисто
65 Гц:  84 500 строк/с  ->  11.83 мкс             полосы
66 Гц:  85 800 строк/с  ->  11.65 мкс             срыв

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

частота = 1 / (число строк × время строки)
1300 строк × 12.82 мкс = 16.7 мс = 60 Гц

Ровно паспортные шестьдесят. Запас — около восьми процентов, и он выбирается на 65 Гц.

Чтобы получить больше, нужно либо строку быстрее (панель не умеет), либо строк меньше (их 1280, это физическое разрешение).


Лицензия и происхождение

Патч — производная работа от hekate, GPLv2. Авторские уведомления CTCaer и naehrwert сохранены во всех затронутых файлах.

Определения регистров DSI — из hekate. Расшифровка структуры замка и снятие третьего уровня — новое.

About

Снятие третьего уровня защиты регистров панели Nintendo Switch OLED (Samsung AMS699VC01) и карта её вендорских регистров

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages