Pull to refresh

Comments 12

Почему КиБ, МиБ? Мигабайт, что ли? Что за абривиатура такая? Автор не отвечает, если кто в теме, поясните.
Ханжество какое-то. Если вас не корёжит от мебибайта, то и пользуйтесь им везде. а то:
«Вектор с миллионом целых после всех аллокаций занимает адрес 3,5 ГиБ + 3 МиБ, как и ожидалось. Первый мегабайт кучи был освобожден и в его...»
ну и почему у вас смешано — миллион, потом ГиБ, потом мегабайт?

Довольно редко есть реальная необходимость уточнять, что мегабайт это 1048576 байт, а вот гигабайт на диске это 10^9 байт. Обычно из контекста вполне понятно о чём идёт речь…
Миллион целых — потому что у меня в цикле действительно миллион, и это размер листа, никакого отношения к байтам. А по поводу мебибайта/мегабайта вы правы, смешиваю. Привычку писать в сокращении выработал, а в тексте пока нет.
Спасибо, поздно увидел ответ, но удалить коментарий на модерации не мог.

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

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

Потому что автор не описывает принципы работы как таковые, это все подробно объяснено как в мануале по процессору, так и в ряде книг, втч на русском языке. Подробно. Автор описывает некоторые конкретные нужные ему аспекты, а на деле все не то что просто, а мега-просто — в конце концов, когда-то я писал свою ОС, работающую в защищенном режиме и было это в 7 классе школы, так что это не rocket science совсем.

Если кратко, то все обстоит так: для страничного преобразования у нас есть некая структура данных (в виде связанных таблиц), каждая ячейка которой соответствует адресу страницы в виртуальном адресном пространстве, а значение этой ячейки — адрес страницы в физической памяти, «на самом деле». Т.е. это просто вульгарный mapping.
У каждого процесса может быть свой такой mapping.
Плюс сегменты — их автор выставлял в прошлых статьях — это в крайнем случае, просто 3 структуры по 8 байт каждая, которые чаще всего делают память «плоской», т.е. каждый сегмент имеет размер в полные 4 Гб.
Сам переход в ЗР — это выставление одного бита в регистре CR0 и 1 long jump, все.

MOV EAX,CR0
OR EAX,1
MOV CR0,EAX ; собственно переход в защищенный режим

JMP PWORD 8:CONTINUE

CONTINUE:
use32

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

Автор описывает некоторые конкретные нужные ему аспекты

Верно, потому что я делюсь своим опытом, в тех вопросах, в которых были проблемы у меня. А если почитать форум OSDev, то видно, что не у меня одного.

когда-то я писал свою ОС, работающую в защищенном режиме и было это в 7 классе школы

Расскажите, как вы организовали кучу и выделение памяти, мультизадачность? Было бы полезно узнать ваш опыт.
Расскажите, как вы организовали кучу и выделение памяти, мультизадачность? Было бы полезно узнать ваш опыт.

Кучу я не организовывал, в моей парадигме это работа менеджера памяти прикладной программы.
Выделение памяти — ничего необычного — хранится информация о физической памяти в виде таблицы «начало участка — размер», по запросу подбирается либо участок нужного размера, либо список участков суммарно необходимого размера. Потом по таблицам страниц/каталогам таблиц ищется место, создается VA маппинг на полученные ранее участки.
Мультизадачность — старомодно, через TSS и аппаратное переключение задач, системные вызовы — через прерывание (тогда и в mainstream системах еще не использовали sysenter), все данные по открытым файлам, по потокам и всему прочему хранятся в пространстве ядра. Это неоптимально, для любой операции надо вываливаться в ядро. Сейчас бы я так уже не делал.
            chunk_count = size / KHEAP_CHUNK_SIZE;
            if KHEAP_CHUNK_SIZE * chunk_count != size {
                chunk_count += 1;
            }

Можно
chunk_count = (size + KHEAP_CHUNK_SIZE - 1) / KHEAP_CHUNK_SIZE;
Sign up to leave a comment.

Articles