Всем привет!
В своей ОС пытаюсь организовать страничную память в защищённом режиме х64, и застрял на структуре каталога страниц PML4E.
На данный момент вырисовывается такая картина, в которой я сомневаюсь.
1. Имеем один каталог PML4 на который указывает CR3. В нём 512 записей/указателей, т.к. в лин.адресе выделяется 9 ст.бит.
2. Если каждая запись PML4E указывает на сл.каталог PDPT, значит всего имеем 512 каталогов PDPT, и в каждом из них тоже по 512 записей. Итого 512*512=256К записей.
3. На сл.уровне PDT аналогично, только получается, что общее число каталогов PDT уже 256К, и в каждом по 512 записей чтоли? Итого 256К*512=128М.
4. Наконец 128М записей в PDT указывают на один из 128М каталогов PT, и в каждом по 512 указателей на физ.фреймы памяти ОЗУ.
5. Итого 128М*512=64.000 М записей PTE, которые адресуют 4-Кбайтные фреймы: итого 64000М*4096=256 ТБ доступной памяти в режиме х64.
6. Если размер одной записи в таблицах =8 байт, тогда выходит, что весь каталог PML4 займёт 64000М*8=512 Гб в памяти.
Ясно, что это связь каталогов при макс.объёме физ.памяти, а на практике нужно создавать "PageTable" при каждой загрузке ОС динамически, по размеру ОЗУ на текущий момент. Вот здесь и непонятно, какое кол-во каталогов на каждом уровне мне нужно выделить? Читал "Intel SDM" и несколько страниц в инете, но вопросы всё-же остались. Сейчас провожу тесты своего загрузчика в QEMU с 1024 Мб памяти так:
1. Запросить полный объём ОЗУ в байтах (можно взять из таблицы smbios).
2. ОЗУ /4096 байт, чтобы получить общее число физ.фреймов PFN.
3. PFN = всего записей в последней таблице PTE.
4. PFN /512 = записей в предпоследней таблице PDT.
5. Если имеется остаток, то отправить его в таблицу предыдущего уровня PDPT.
6. Повторить пункт 5, и остаток отправить в PML4.
Как результат, для 1 ГБ получаю следующую схему.. На правильном я пути или нет?
В своей ОС пытаюсь организовать страничную память в защищённом режиме х64, и застрял на структуре каталога страниц PML4E.
На данный момент вырисовывается такая картина, в которой я сомневаюсь.
1. Имеем один каталог PML4 на который указывает CR3. В нём 512 записей/указателей, т.к. в лин.адресе выделяется 9 ст.бит.
2. Если каждая запись PML4E указывает на сл.каталог PDPT, значит всего имеем 512 каталогов PDPT, и в каждом из них тоже по 512 записей. Итого 512*512=256К записей.
3. На сл.уровне PDT аналогично, только получается, что общее число каталогов PDT уже 256К, и в каждом по 512 записей чтоли? Итого 256К*512=128М.
4. Наконец 128М записей в PDT указывают на один из 128М каталогов PT, и в каждом по 512 указателей на физ.фреймы памяти ОЗУ.
5. Итого 128М*512=64.000 М записей PTE, которые адресуют 4-Кбайтные фреймы: итого 64000М*4096=256 ТБ доступной памяти в режиме х64.
6. Если размер одной записи в таблицах =8 байт, тогда выходит, что весь каталог PML4 займёт 64000М*8=512 Гб в памяти.
Ясно, что это связь каталогов при макс.объёме физ.памяти, а на практике нужно создавать "PageTable" при каждой загрузке ОС динамически, по размеру ОЗУ на текущий момент. Вот здесь и непонятно, какое кол-во каталогов на каждом уровне мне нужно выделить? Читал "Intel SDM" и несколько страниц в инете, но вопросы всё-же остались. Сейчас провожу тесты своего загрузчика в QEMU с 1024 Мб памяти так:
1. Запросить полный объём ОЗУ в байтах (можно взять из таблицы smbios).
2. ОЗУ /4096 байт, чтобы получить общее число физ.фреймов PFN.
3. PFN = всего записей в последней таблице PTE.
4. PFN /512 = записей в предпоследней таблице PDT.
5. Если имеется остаток, то отправить его в таблицу предыдущего уровня PDPT.
6. Повторить пункт 5, и остаток отправить в PML4.
Как результат, для 1 ГБ получаю следующую схему.. На правильном я пути или нет?
.