Привет, хабровчане! В прошлой теме я рассказывал, как мы с командой производили (и дальше производим) ромхакинг такой игры, как Xenoblade Chronicles на Nintendo Wii. Я бы хотел рассказать о менее простой, но интересной теме – устройство хранения файловой системы у Nintendo GameCube. Так уж вышло, что я полюбил данную консоль и никак не мог упустить шанс рассказать о её технической стороне, хоть и малой. Не будем затягивать, начнём!

Введение


Как понятно по названию темы, речь пойдёт о том, как устроена файловая система Nintendo GameCube, а если быть точнее, то как устроена файловая система дисков. Давайте поговорим о том, какие всё такие диски использовались на Nintendo GameCube. Прошу Вас выйти из дома в гараж, сесть в DeLorean и отправиться в начало нулевых. На дворе 2001 год, на рынке игровых консолей уже как год властвует Sony PlayStation 2 и выходит оно – Nintendo GameCube. Мощнее начинка, больше потенциал, но почему продажи не так высоки, как у PlayStation 2? Крикнем “Спасибо!” Nintendo и их политике от пиратства и тому чудовищу, которое они решили использовать в своей консоле в качестве носителя информации – собственно разработанный miniDVD диск. Что он из себя представлял и почему смог погубить такую потенциальную консоль, спросите Вы? А я отвечу, представлял он из себя по размеру половину DVD диска, а вот проблемой стал малый объем в размере 1,5ГБ (против 4,7ГБ у DVD диска на PlayStation 2). Это чисто моё личное мнение, но именно данный диск и погубил продажи данной консоли. Об этом можно говорить много, но всё же вернёмся к основной теме. Да, Nintendo изобрели для GameCube свой собственный диск объёмом в 1,5ГБ, что категорически не хватало крупным играм, из-за чего их разделяли на несколько дисков (привет 90-е). Приходилось использовать кучу разных алгоритмов сжатия, как-то сокращать игры, чтобы они влезли на диск. Ладно, хватит о грустном, пора вернуться к основной теме.

Техническая составляющая


Как я сказал выше, диск имел объем в 1,5ГБ. С таким объёмом использовать всем прижившуюся ISO9660 или её модификацию было явно нерентабельно. Nintendo пошли другим путем – они разработали свою технологию описывания файловой системы, её основой стал блок FST (FileStringTable). Данный блок компактный и хранит всю нужную информацию о файлах, о нём я ещё расскажу побольше, но об этом чуть позже.

Весь игровой образ можно разделить на 6 блоков:

  1. Основная информация (boot.bin)
  2. Дополнение к основной информации (bi2.bin)
  3. Apploader (apploader.img)
  4. FileStringTable (fst.bin)
  5. DOL (main.dol)
  6. Основные данные

Предлагаю рассмотреть каждый блок отдельно. Для примера использовался первый диск европейской версии Resident Evil Code Veronica X (GCDP08).

Основная информация, блок boot.bin




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

class gcmBoot
{
	public uint gameCode;
	public ushort makerCode;
	public byte diskID;
	public byte version;
	//seek to 0x1C
	public uint DVDMagicWord; //0xC2339F3D
	public string gameName;
	//seek to 0x420
	public uint offsetMainDol;
	public uint offsetFST;
	public uint sizeFST;
}

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

Дополнение к основной информации, блок bi2.bin


Данный блок, как и прошлый, имеет фиксированный размер, правда на этот раз его размер 0x2000 байт, а начинается он строго после boot.bin (0x440). Сказать о нём мне нечего, он содержит в себе информацию для debug режима.

Apploader




Данный блок, как понятно по название, отвечает за загрузку образа, парсинга FST, инициализацию модулей, запуска DOL файла. Рассказать о нём, как и о bi2.bin мне нечего, так что идём дальше.

FileStringTable, блок fst.bin




Вот мы и добрались до самого интересного, данный блок содержит в себе разметку всех файлов, находящихся в образе: имена файлов и папок, их смещение и размер. Начинается он с адреса gcmBoot>offsetFST и имеет размер gcmBoot>sizeFST.

Его структура такова:

class gcmFST
{
	public byte flags; // 0: File; 1: Dir;
	public uint offsetName;//Real size 3 byte
	
	//if flags = 0
	public uint fileOffset;
	public uint fileSize;
	
	//if flags = 1 
	public uint dirParent;
	public uint dirNext;
}

Попробую разъяснить полегче:

1 байт предназначается для определения, идёт информация о файле или о папке. 3 остальных байта предназначаются для указателя на строку с именем файла или папки (указатель начинается с начало блока с именами файлов\папок, а не с начала блока FST).

Если первый байт равен 0 (файл), то следующие 8 байт значат:

  1. 4 байта – указатель на файл в образе
  2. 4 байта – размер файла

Если же первый байт равен 1 (папка), то следующие 8 байт значат:

  1. 4 байта – номер папки, в которой находится данная папка
  2. 4 байта – номер элемента, на котором заканчиваются элементы в данной папке

С файлами всё просто и понятно, а вот с папками не очень. Но, я здесь для того, чтобы вам всё объяснить. К примеру, папка находится в корне диска, имеет название habr, dirParent равен 0 (т.к. в корне диска), а вот dirNext имеет значение 6. Сама папка находится 3 элементом в блоке FST, следовательно, все последующие элементы ровно до 6 элемента будут находится в папке habr, то есть элемент 4 и 5.

Самое главное, о чём забыл сказать, так что 0 блок (то бишь первый) является ссылкой на корень диска, он не имеет имени в блоке с названиями элементов, хоть и имеет указатель. Это просто надо учитывать и ничего более.

Как видите, благодаря подобной структуре, она имеет очень малый размер (если сравнивать с ISO9660 и её модификациями).

DOL




Как говорится, сердце игры. Как у Windows – EXE, так и на GameCube – DOL. Блок с основным исполняемым файлом. Конечно, были и игры, где использовался иной исполняемый файл, хранимый с основными игровыми файлами, но, чаще, никто так не извращался, слава богу.

Ну что ж можно рассказать о нём? Простой исполняемый файл, разделённый на секции:

  1. Семь TEXT секций (код)
  2. Одиннадцать DATA секций (данные)

Основные данные


И последний блок, который свою суть рассказывает по названию. Это блок идёт до конца файла и содержит в себе все файлы, выровненные по 2048 байт. Ходит легенда, что для экономии места можно выровнять эти файлы не по 2048 байт, а по 4 байта. И даже работать будет, на эмуляторе так точно. А вот убить лазер таким способом Вам точно не составит труда.

Заключение


В данной теме я попытался раскрыть, как Nintendo послала всех куда подальше и разработала простую, но всё же интересную и компактную файловую систему. Конечно, она не подойдёт для использования на домашних ПК из-за её особенностей хранения файлов. Данная файловая система не хранит в себе никаких флагов, кроме как File\Dir, не хранит время создания файла, EDC\ECC каждого сектора и т.п информацию, которая имеется в ISO9660. Но, она здесь и не нужна. Nintendo разработали такую компактную файловую систему, чтобы предоставить больше места для игровых данных. Ведь зачем диску с игровой системы хранить время создания файла и т.п.?
Спасибо за внимание.
Поделиться с друзьями
-->

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


  1. freeart
    25.07.2017 10:18
    +2

    А какой выигрыш в цифрах давала такая оптимизированная файловая система по сравнению с ISO9660? Мне кажется там разница на несколько десятков мегабайт.


  1. GeMir
    25.07.2017 12:41

    Размер в 0x440 байт
    «1088 байт» читаются в тексте заметно легче, неправда ли?
    В прошлой теме […] Как понятно по названию темы […] В данной теме
    Статье, статьи?


  1. ka9koss
    25.07.2017 15:23

    Спасибо, интересная статья!


  1. darakanoit
    25.07.2017 15:23

    Спасибо! Довольно интересно, но зачем? -Ограничить пиратство? В итоге PS2 стала легендой.


  1. nickkee
    25.07.2017 19:08

    Всегда уважал вот таких вот хакеров стареньких консолей, сразу видно, что не за бабки работа сделана, а для души :)