Я работаю над дизайном ядра, и у меня есть вопросы по разбиению на страницы.
Основная идея, которой я придерживался до сих пор, такова: каждая программа получает свой собственный (или так думает) 4G памяти, за вычетом какого-то раздела, который я резервирую для функций ядра, которые программа может вызывать. Итак, ОС должна придумать способ загрузки страниц в память, которые программа должна использовать во время своей работы.
Теперь, предполагая, что у нас есть бесконечное количество памяти и процессорного времени, я мог бы загрузить / выделить любую страницу, которую программа написала или прочитала, как это произошло, используя ошибки страниц для страниц, которые не существуют (или были выгружены), поэтому ОС мог бы быстро выделить их или поменять местами. Однако в реальном мире мне нужно оптимизировать этот процесс, чтобы у нас не было программы, постоянно потребляющей всю память, к которой она когда-либо обращалась.
Итак, я предполагаю, что мой вопрос в том, как ОС вообще справляется с этим? Моя первоначальная мысль - создать функцию, которую программа вызывает для установки / освобождения страниц, которыми она затем может управлять памятью самостоятельно, но делает ли это программа обычно, или компилятор предполагает, что у нее есть свобода действий? Кроме того, как компилятор обрабатывает ситуации, когда ему необходимо выделить довольно большой сегмент памяти? Нужно ли мне предоставлять функцию, которая пытается упорядочить X страниц?
Это, очевидно, вопрос не для конкретного языка, но я неравнодушен к стандарту C и хорошо разбираюсь в C ++, поэтому я хотел бы, чтобы любые примеры кода были либо в этом, либо в сборке. (В сборке нет необходимости, я полностью намерен заставить ее работать с максимально возможным количеством C-кода и оптимизировать в качестве последнего шага.)
Еще одна вещь, на которую также должно быть проще ответить: как обычно обрабатываются функции ядра, которые программа должна вызывать? Можно ли просто иметь заданную область памяти (я думал о конце виртуального пространства), которая содержит самые основные функции / память для конкретных процессов, которые программа может вызывать? Моя мысль оттуда заключалась в том, чтобы функции ядра делали что-то очень необычное и меняли страницы (чтобы программы не могли видеть важные функции ядра в своем собственном пространстве), когда программам нужно было делать что-то важное, но я не совсем сосредоточив внимание на безопасности на этом этапе.
Так что я думаю, что меня больше беспокоят общие идеи дизайна, чем детали. Я хотел бы сделать ядро полностью совместимым с GCC (каким-то образом), и мне нужно убедиться, что оно предоставляет все, что может понадобиться обычной программе.
Спасибо за любой совет.