LINUX.ORG.RU
ФорумTalks

Memory Management Unit (MMU) в ARM и прочих

 ,


1

2

Некоторые ARM процессоры не имеют встроенного MMU. По каким-то причинам производители процессоров зачастую не встраивают поддержку страничной виртуальной памяти в свои устройства, а заменяют её на более простые технологии.

Вопросов на эту тему несколько:

1. Какие причины заставляют разработчиков отказываться от MMU?

2. Каким образом Linux может работать на архитектурах, не поддерживающих виртуальную память?

3. Какова сложность подсистемы MMU на кристалле и разбирался ли кто-нибудь с принципами её работы?

Хотелось бы услышать мнение о возможности сделать MMU, поддерживающий несколько размеров страниц. Например - 1Кб, 2Кб, 4Кб, 8Кб, 16Кб, 32Кб, 64Кб, 128Кб, 256Кб, 512Кб, 1Мб, 2Мб, 4Мб, 16Мб. Т.е. процессор должен поддерживать одновременно все перечисленные размеры страниц.

И ещё один вопрос, возможно ли, хотя бы теоретически, имея исходниый код какого-либо микропроцессора на VHDL/Verilog, добавить к его системе команд свою команду? Насколько это сложно, если бы такую задачу поставили вам? Время, цена вопроса?

Вообще-то я лукавил, говоря насчёт одной команды - одна команда, которая выполняет микропрограмму, которая меняет значение многих регистров, может копировать блоки памяти и осуществляет синхронизацию.

Интерес пока праздный, но в будущем хотелось бы заняться этим.

Наконец, прошу ссылок на различные реализации CPU, вне зависимости от архитектур и лицензий.

★★★

Ответ на: комментарий от alman

Они ушли от оригинальных многослойных отображений памяти и синхронных IPC. Я считаю, что это все не просто так. Видимо, оригинальные концепции слишком суровы для практического применения.

AptGet ★★★
()
Ответ на: комментарий от AptGet

Они ушли от оригинальных многослойных отображений памяти и синхронных IPC.

Ушли от синхроннных IPC? Да они с ума сошли! Это же священная корова! Вот аргументы за синхронные IPC:

1. Пропадает необходимость в объктах синхронизации, прежде всего в критических секциях.

2. Не нужно городить дополнительные очереди сообщений - приёмник сообщений может выделять буфер несоредственно перед приёмом сообщения.

3. Синхронные IPC можно (и нужно) реализовать в виде команды в железе, с аснинхронными такой трюк вряд-ли пройдёт или будет в 10 раз сложнее.

Многослойные отображения памяти - да, эту штука весьма муторная и этот топик имеет к ней непосредственное отношение. Но фишка в том, если этот сложный алгоритм реализовать в железе и с умом использовать flexpages, то получаются простые и эффективные алгоритмы работы с памятью.

alman ★★★
() автор топика
Ответ на: комментарий от tailgunner

Ы? Singularity была написана на управляемом языке и не требовала никакой VM.

Что-то она не хочет загружаться ни в VMWare, ни в VirtualBox. Кто-нибудь видел её в работе?

А в чем проблема?

К примеру, старый добрый malloc. В юниксах он работает просто - при первом вызове он обращается к системе системным вызовом sbrk и добавляет памяти к куче процесса. Затем уже блоки памяти распределяются из кучи. Если в куче не нашлось свободного места достаточного размера, то malloc опять вызывает sbrk и увеличивает размер кучи. Собственно вопрос - как реализовать системный вызов sbrk на безопасном языке?

alman ★★★
() автор топика
Последнее исправление: alman (всего исправлений: 1)
Ответ на: комментарий от alman

Мне нравятся синхронные IPC (из-за простоты и ортогональности), но они плохо ложатся на реальный мир. И вынуждают плодить нити, такие приложения сложно отлаживать.

AptGet ★★★
()
Ответ на: комментарий от alman

Что-то она не хочет загружаться ни в VMWare, ни в VirtualBox. Кто-нибудь видел её в работе?

Я - нет, но у меня нет никаких причин подозревать MSR во вранье.

К примеру, старый добрый malloc. В юниксах он работает просто - при первом вызове он обращается к системе системным вызовом sbrk

Он давно работает не так, но суть не в этом...

как реализовать системный вызов sbrk на безопасном языке?

Ровно теми же манипуляциями с таблицей страниц, что и на небезопасном. В чем проблема-то?

tailgunner ★★★★★
()
Ответ на: комментарий от AptGet

Мне нравятся синхронные IPC (из-за простоты и ортогональности), но они плохо ложатся на реальный мир.

Позволь, я отвечу длинным рассказом. Давным-давно я захотел написать операционную систему, долго шёл к этой цели и делал разные попытки. Работая программистом в Южной Корее, увидел здесь (linux.org.ru) ссылку на L4 Fiasco, в результате чего родился проект консоли (http://savannah.nongnu.org/projects/l4-console/). Мне не понравился IDL (о технологии COM я тогда не слышал), поэтому придумал протокол эмуляции ANSI терминала, точнее протокол для управления символьными устройствами. Нечего нового - open, read, write, close, ioctl - пять системных вызовов на основе синхронных IPC.

Затем мне попался L4Ka Pistachio, и я понял, что все предыдущие попытки написать операционную систему были лишь обучением. Консоль была перенесена на Pistachio, затем из корневой задачи переместилась в отдельный процесс, а для этого появился новый корневой процесс - Супервизор. Супервтзор стал оперировать понятиями - Процесс, Задача (thread), Динамические сегменти памяти, Сигналы и Таймеры. Для управления этими ресурсами были разработаны системные вызовы на основе синхронных IPC. Таким образом Супервизор мог стартовать модуль ANSI терминала в как своём локальном адресном прострастве (как задача), так и в выделенном - как процесс. Имела ли смысл эта разработка? По образу и подобию с ANSI терминалом был написан драйвер RS-232 (open, read, write, close, ioctl). Около семи лет назад я мог превратить любой PC-AT386 в аппаратный ANSI терминал. НИКАКИХ проблем с синхронностью соообщений на такой конфигурации не было и быть не могло. Но кому в 2005 году нужен аппаратный ANSI терминал? Никому. Поэтому разработка ушла в бэкапы и я занялся кое-чем другим.

Два посекторных образа 1.44 дискет плюс MS Visual Studio могут родить проект файловой системы. Простая консольная программа, которая загружает образ диска в память, эмулирует посекторные запись/чтение, производит разбор структур данных загруженных образов. В результатом консольная программа трансформировалась в библиотеку, реализующую подмножество функций работы с файлами на основе posix. В качестве блочных устройств библиотека использовала образы дисков.

Затем весь API библиотеки был реализован на сообщениях L4-X2 и для каждого сообщения был написан системный вызов libc. В результате библиотека работы с образами дисков трансформировалась в процесс «Файловая система», реализующий некоторое подмножество функций работы с файлами и директориями и «понимающий» два формата исполняемых файлов Elf и WinPE. Понимал в том смысле, что умел их загружать и готовить к старту.

В общем, долго рассказывать обо всех подробностях, может когда-нибудь в другой раз. Речь идёт о реальном мире и в какой-то момент, когда заработал fork, две пользовательские задачи «подрались» за ресурсы файловой системы - обе обратились к сервису терминала и вот только тут выползла проблема синхронности. Пока не был обслужен вызов первой программы, второй блокировался. Обслуживался первый и блокировался при следующем обращении к терминалу - его блокировал второй. Процитирую:

И вынуждают плодить нити, такие приложения сложно отлаживать.

Вот вот вот! Я забросил разработку, потому что не мог решиться на то, чтобы плодить нити. Те, кто решились - быстро разочаровались в микроядрах - получалось монстрообразное и тормозное решение, сводящее на нет все преимущества микроядер - микроядро выстапало как дополнительный и ненужный слой абстракции, пожирвающий память и такты CPU.

А что если не плодить нити, а как-нибудь хитро реализовать обслуживание? Почему была блокировка? Потому-что, получив запрос на ввод от пользовательской задачи, файловая система передала сообщение далее в задачу, обслуживающую ANSI терминал и находится в ожидании ответа - нажатия на клавишу пользователем. А что если ожидать ответ от терминала и новый запрос от любой другой задачи в одной точке? В смысле - просто ожидать событие от любого источника, а по приходу события просто переключить контекст - пришёл ответ от терминала, обрабатываем и отвечаем первой задаче. Пришёл запрос от другой задачи - перелючаем контекст, направлеям ещё одирн запрос терминалу и опять в ожидание события. БЛОКИРОВОК НЕТ! Их просто нет, им не откуда взяться. Обслуживание в одном потоке без блокировок.

alman ★★★
() автор топика
Ответ на: комментарий от tailgunner

Ровно теми же манипуляциями с таблицей страниц, что и на небезопасном. В чем проблема-то?

Возможно я отстал от жизни, C# безопасный язык или нет? Разбирал как-то TrueType фонты на сишарпе, так весь код пестрит Marshal.Copy, Marshal.PtrToStructure, Marshal.StructureToPtr и т.д.

В ядре такие вещи не очень хороши с точки зрения быстродействия. imho

alman ★★★
() автор топика
Ответ на: комментарий от alman

Возможно я отстал от жизни, C# безопасный язык или нет?

C# - это другая ветка развития. Cyclone и Rust - это потомки Си, а не Явы.

просто ожидать событие от любого источника

Ты изобрел мультиплексирование? А структуры данных, поддерживающие ожидание событий из нескольких источников, ты уже спроектировал?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А структуры данных, поддерживающие ожидание событий из нескольких источников, ты уже спроектировал?

Это ещё 2005 году работало и сейчас работает. Из новостей - 64-бита и реализация poll на символьные устройства.

К примеру, старый добрый malloc. В юниксах он работает просто - при первом вызове он обращается к системе системным вызовом sbrk

Он давно работает не так, но суть не в этом...

Возможно он не так сейчас работает в Linux, но именно так он работал в первых *никсах. Да и кто сказал, что Linux работает с памятью единственно правильным способом?

alman ★★★
() автор топика
Ответ на: комментарий от alman

А структуры данных, поддерживающие ожидание событий из нескольких источников, ты уже спроектировал?

Это ещё 2005 году работало

Мультиплексирование (select) работало еще в 70-х, так что вопрос не в этом... ты добавил в API микроядра операцию «ждать сообщение из нескольких источников»? Если да, то ты либо должен сопровождать каждое сообщение идентификатором источника, либо сопровождать вызов ожидания списком всех возможных источников.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

ты добавил в API микроядра операцию «ждать сообщение из нескольких источников»?

Не добавлял - изначально присутсвует как одна из форм IPC. Все виды посылок и приёма сообщений в результате транслируются в один IPC, который собственно и хотелось бы видеть в виде команды процессора.

Если да, то ты либо должен сопровождать каждое сообщение идентификатором источника,

Любое сообщение уже несёт в себе идентификатор источника - это идентификатор задачи, пославшей сообщение. By design.

либо сопровождать вызов ожидания списком всех возможных источников.

Константа L4_anythread заменяет список всех возможных источников.

alman ★★★
() автор топика
Ответ на: комментарий от alman

Константа L4_anythread заменяет список всех возможных источников.

Ты всегда ждешь сообщения от любой задачи в системе?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ты всегда ждешь сообщения от любой задачи в системе?

Не всегда, но когда нужно превратить синхронные сообщения в асинхронные. Например, в файловой системе - от любой задачи.

alman ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.