Виртуальная Память в Windows Mobile 6.5 и как она отличается от 6.1 и 6.0, важно, когда портируем на устройства, не имеющие Нативное ядро WM6.5 (как раз наш случай, "спасибо" Йота).
Вольный перевод для самого себя.
О Виртуальной Памяти на ru.wikipedia.org
Виртуальная Память, как это применимо к ядру Windows CE 5.2
Общее количество потенциально доступной памяти для WM при используемой 32 битной адресации - 4Гб. Это общее четырёх гигабайтное адресное пространство разбито на две половины - два гигабайта для ядра, два гигабайта для Пользователя. Адресное пространство ядра доступно исключительно для процессов/задач с уровнем доступа ядра, а пользовательское адресное пространство доступно для использования процессами/задачами с любым уровнем доступа.
Пользовательское адресное пространство расположено от 0x00000000 до 0x7FFFFFFF.
Адресное пространство ядра расположено от 0x80000000 до 0xFFFFFFFF.
Пользовательское адресное пространство разбито на 64 слота по 32Мб каждый. (64*32=2048, или 2Гб) - первые 33 слота (слот 0 и 1-32) используются под процессы, а остальные слоты для хранения объектов, отображённые файлы на память (Отображение файла на память) и ресурсы.
Каждый слот легко вертуализируется в HEX'е, вы просто увеличиваете число.
Слот 0: 0x00000000 в 0x01FFFFFF,
Слот 1: 0x02000000 в 0x03FFFFFF,
Слот 2: 0x04000000 в 0x05FFFFFF, ну и так далее.
Каждый процесс получает привязку к собственному слоту, всего их 33 в общем, минус процессы ядра, которые всегда запущены, поэтому Вы получаете ограничение в 32 процесса (которых на практике всегда меньше потому, что существуют постоянно запущенные процессы WM для поддержания OS) - это кстати является причиной ограничения в 32Мб для каждого процесса - как мы видим, это и есть адресное пространство, доступное для одного слота.
Как всё это сказывается на нашей ситуации с модулями? Когда Вы создаёте модуль, Вы задаёте WM, что хотите, чтобы этот модуль стал отображён на память (Отображение файла на память), следовательно, при каждой загрузке он будет загружаться в одну и ту же, известную часть памяти - сохраняя пространство в Слоте 0 - это делается на стороне компьютера, в процессе "кукинга" и это работа wmreloc, g'reloc, bepe Platrorm Rebuilder'а и т.д. Виртуальная разметка привязана к 64Кб бордюру, поэтому, если вы отображаете на память ДЛЛку (.dll) размером в 3Кб, она всё ещё поглощает пространство в 64Кб.
Существуют так же страницы, которые могут быть размещены в этих слотах, привязанных к 4Кб границе и процессуальным/главным привязкам, занимающим место при нормальных операциях. Способ, при котором система использует этот метод заключается в том, что модули размещены в процессе построения rom'а (модули, которые мы размещаем с помощью g'reloc'а и других) размещены сверху вниз (для слота 1 к примеру, начало в 0x03FFFFFF для первого модуля, занимает место до нижестоящей 64Кб границы, потом идет следующий модуль, на линию ниже к адресу 0x02000000, который является началом слота) - Главные расположения, которые используют место в процессе нормальных системных операций расположены в требующемся месте, снизу вверх (и вот снова со слотом 1 к примеру, начало в 0x02000000 и окончание в 0x03FFFFFF) - когда Вы заполняете эти слоты модулями всё больше и больше, они оставляют всё меньше и меньше места для Windows, чтобы динамически размещать другие, Главные размещения, которые могут стать и становятся результатом ошибок выпадания из памяти (даже, когда на устройстве остаётся ещё много свободной физической памяти, она не может быть адресована, т.к. виртуальная память уже заполнена).
Вот и пришло время для рассмотрения различий между 6.0/6.1/6.5 - существует всего 4 слота, которые могут быть использованы для модульного размещения, Слот 0, 1, 60 и 61. Слот 63 так же доступен для модулей, не содержащих кода (модули, содержащие исключительно ресурсы, наподобие .mui).
WinMo 6 должна размещать слот 0, 1 - (в порядке: 1 - первым, 0 - последним), для общих 64Мб пространства Виртуальной Памяти доступного для модулей/файлов (и запущенных процессов, всегда отображённых на Слот 0, поэтому, когда Вы впервые вторглись в это пространство памяти, Вы убрали доступную память для каждого запущенного приложения) - Вы можете увидеть, как это тяжело.
WinMo 6.1 улучшено в этом отношении открытием слотов 60 и 61 (теперь порядок размещения таков: 61, 60, 1, 0) - но модули не могут быть тут размещены. Только файлы. По этому, для наших перераспределительных инструментов это не несёт никаких коренных изменений. (Всё ещё только слоты 1 и 0 для модулей) WM 6.1 так же представляет процесс initvmmap.exe в MSXIPKernel, NK partition (xip.bin). Этот процесс расчерчивает карту всей виртуальной памяти и использует следующий ключ реестра из загрузочной ветки (boot.hv):
[HKEY_LOCAL_MACHINE\System\Loader\ModuleInfo] [HKEY_LOCAL_MACHINE\System\Loader\ModuleInfo\dllname.dll] "filename.exe"=dword:1 "filename2.exe"=dword:1
Это сообщает системе, что модуль dllname.dll требуется только когда запускается filename.exe или filename2.exe, а когда эти процессы не запущены, место в виртуальной памяти доступно и может быть динамически использовано системой.
WinMo 6.5 улучшена в этом отношении открытием Слотов 60 и 61 для модулей - уступая дополнительные 64 мегабайта пространства доступной виртуальной памяти. (Порядок размещения теперь таков: 1, 61, 60, 0 - для модулей и 60, 61, 0 - для файлов) - чтобы ядро могло распознать, что эти новые Слоты были размечены для модулей, они должны быть обновлены до уровня базы кодов 6.5 Это как раз то, как 6.5 nk.exe используется и почему это так важно.
Профилирование Виртуальной Памяти - это важнейшая работа для OEM - наименьшая доступность к Слоту 0, из-за наибольшей вероятности, что устройство начнет выдавать ошибки выпадания из памяти (даже если реально выпадания из памяти не происходит) - это худший расклад, который может получить пользователь. Некоторые ROM'ы, которые я наблюдал, имели менее 20Мб в Слоту 0 (результат для пользователя был настолько ужасным, что представить сложно) - появлялось множество сложностей для цельных процессов - таких как балансирование загрузки между services.exe и device.exe для наибольшей пользы использования 32Мб Виртуальной Памяти, доступной каждому из этих процессов и размещение всех ресурсных ДЛЛок как модулей, доступных к размещению в Слот 63 и т.д.
Это дополнительно подчёркивается, как это важно, что перераспределяющие инструменты обновлены для поддержки новых слотов - g'reloc не будет даже пытаться размещать модули в Слоты 60 и 61 потому, что это опасно и даже невозможно. На данный момент мне известно два инструмента, которые будут перераспределять на слот 60 и 61 - wmreloc 2.0 и bepe's Rebuilder (используется ervius vk).
Какие же "домашние задания" будут в отношении Виртуальной памяти?
Держите Слот 0 настолько свободным, насколько это вообще возможно. WM 6.5 NK даёт Вам возможность использовать больше модулей без занятия пространства Слота 0, даёт больше гибкости для использования модулей (которые быстрее загружаются).
Перевод ужасен, надо еще дорабатывать, т.к. понимание переведённого текста лично у меня на данный момент низкое =)