OSDev

для всех
Текущее время: 06 дек 2019, 13:41

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 15 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: 07 окт 2019, 17:19 

Зарегистрирован: 26 янв 2019, 14:00
Сообщения: 34
Добрый день!
Возникла трудность на стадии представления как вообще реализовать взаимосвязь между процессами пользовательского пространства. В общем что имею: могу загружать программы в изолированные пространства, есть маленькая стандартная библиотека с системными вызовами. Пытаюсь реализовать такую схему: первый процесс реализует систему "окон" и вызывает необходимые программы для запуска других каких нибудь программ. Для начала хочу чтобы "оконный" менеджер вызывал терминал, а дальше уже и так понятно.
Тут мне не дает покоя проблема связи родительского процесса и пользовательским. К примеру как реализовать передачу адреса буфера окна из менеджера окон в дочерний процесс.
Один из вариантов которых нашел сопоставить физические адреса родителя и ребенка. Но даже так этот процесс кажется очень сложным когда между родителем и ребенком есть n-ое количество процессов. Собственно такое же недопонимание с событиями мыши и клавиатуры. Ведь эти данные проходят через менеджер окон и уходят активному окну/процессу.
Второй вариант писать все на хард и тащить оттуда, но это затратно и не безопасно.
Может можете подсказать что то по этому поводу?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 18:41 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1401
Если я правильно понял, нужна возможность совместного использования несколькими процессами (в терминах Винды) общей части адресного пространства. Соответственно, ОС должна предоставлять сервисы для отображения заданной части виртуального адресного пространства (ВАП) одного процесса на заданную же часть ВАП другого процесса. Например, некий "обычный" процесс (грубо говоря, калькулятор, блокнот и т.п. программа) хочет обратиться к системному процессу, заведующему реальной отрисовкой, чтобы нарисовать, скажем, окно. Тогда этот обычный процесс дёргает ОС, а та передаёт запрос на фактическое выполнение системному процессу. Последний, получив через ОС адрес и размер буфера с управляющей информацией, обращается к ОС с требованием отобразить кусок своего ВАП на этот буфер в ВАП вызывающего процесса, и дальше работает с ним как со своей собственной памятью.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 19:05 

Зарегистрирован: 26 янв 2019, 14:00
Сообщения: 34
Спасибо, концепцию понял. Однако сразу возник вопрос, не слишком ли затратная вещь постоянно дергать ядро? Т.е. это каждый раз переключаться из режима ядра в режим пользователя и обратно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 19:15 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1401
Затратно, конечно, но получить безопасность без вмешательства ядра в общем случае невозможно (более-менее можно лишь при наличии железной поддержки, а таковая, в принципе, имеется в 16- и 32-разрядном защищённых режимах IA-32 (но не в 64-разрядном, где сегментацию выпилили) и в IBMовских мэйнфреймах, но и в этих случаях подготовительная работа со стороны ядра необходима -- заполнить, например, дескрипторы сегментов, чтобы обеспечить разрешённые виды доступа). Но, если обмен нужен постоянно (скажем, при работе обычной проги с менеджером окон), можно, например, системным вызовом создать в ВАП "окно" для связи (область, куда оба процесса имеют доступ), а в дальнейшем общаться через это окно, не дёргая систему вообще или дёргая её минимально. Например, в нём можно организовать очередь сообщений друг для друга, причём добавлять-удалять сообщения атомарными операциями. Тогда, например, когда активен менеджер окон, он обрабатывает свою очередь, выдёргивая из неё элементы, до тех пор, пока очередь не опустеет, после чего вызовет систему, чтобы отдать проц другому процессу (например, Wait на 10 мс). При таком подходе ОС дёргается лишь для создания/уничтожения общего адресного окна, а также в случаях, когда у процесса нет работы.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 20:09 

Зарегистрирован: 26 янв 2019, 14:00
Сообщения: 34
SII, спасибо большое за ответ.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 21:28 

Зарегистрирован: 26 янв 2019, 14:00
Сообщения: 34
Сейчас понял вот что. Точнее не понял. А как организуется тоже самое в микроядрах? По ее концепции загружаем в память процесс "драйвера" в пользовательском режиме когда он понадобился. А что потом, собственно как к нему обращаться? Снова через ядро? Это было бы логично. Однако в отличии от обычного процесса нет так называемой функции main, зато есть множество других. К примеру если это драйвер накопителей, как минимум чтение и запись. Как собственно определяют по какому адресу функция и как к ней обращаться?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 22:17 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1401
Базовый вариант -- обмен сообщениями с предопределёнными кодами и форматами данных. Тогда любой процесс (драйвера, скажем) создаёт некий почтовый ящик, в который микроядро кидает сообщения от других процессов. Соответственно, микроядру незачем знать какие-либо интимные подробности о внутренностях других процессов и т.д.; оно, по сути, реализует лишь две функции -- переключение "низкоуровневых потоков" (т.е. того, что реально выполняется процессором) и передача сообщений, всё остальное реализуется внешними по отношению к ядру программами.

Поскольку любой обмен требует кучи переключений, настоящее микроядро на большинстве платформ будет весьма неэффективным (замечу: при прочих равных, ибо тщательно написанная микроядерная ось вполне может быть эффективней хреново написанного монолита, ну а нынешние компиляторы вовсю стремятся сделать любой ход хреновым; лично у меня стойкое ощущение, что Фортран и ПЛ/1 из ОС/360 конца 60-х/начала 70-х давали лучший код, чем современные компиляторы). Если имеется аппаратная поддержка (сегментация на ИА-32 и механизмы адресных программ и вызова программ по номеру на ИБМовских мэйнфреймах), микроядерность можно реализовать довольно эффективно, так как в такой ситуации большинство обращений могут ходить напрямую между программами без привлечения ядра. Но в любом случае правила взаимодействия являются предопределённой вещью, но это, думаю, очевидно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 07 окт 2019, 22:46 

Зарегистрирован: 26 янв 2019, 14:00
Сообщения: 34
SII, я правильно понял вас, в том что. по вашему мнению. микроядра без написания так скажем специализированного компилятора не имеет смысла? Очень интересная информация, ибо крайне мало информации касательно микроядер, да и пишут их видимо редко.
А как реализуется обмен сообщениями? Я уловил вашу аналогию с почтовым ящиком, идея очень интересно звучит, мне уже чисто из любопытства интересно стало как это) Получается создается некий дополнительный буфер для каждого нового процесса? И все равно не могу себе представить как именно обращаясь к драйверу мы сможем запросить чтото конкретное сделать. Поидее ведь нужно заранее знать что он может. Или тут я не прав?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 08 окт 2019, 05:17 

Зарегистрирован: 28 окт 2007, 18:33
Сообщения: 1401
Компиляторы здесь принципиальной роли не играют; я говорил про низкую эффективность микроядер, если для них нет аппаратной поддержки со стороны процессора -- а в подавляющем большинстве случаев это так. Такая поддержка нужна для передачи управления из одного адресного пространства в другое без вмешательства ОС, но при этом с гарантированным обеспечением защиты -- т.е. чтобы кто угодно не мог прыгнуть куда угодно.

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

Ну а заранее знать, кто что может, нужно в обязательном порядке, без этого никак. По большому счёту, нет никакой разницы, какая именно ОС: если приложение хочет произвести запись в файл, оно в конечном счёте должно запросить операцию записи в том виде, в каком это принято в данной ОС.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 08 окт 2019, 06:26 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1120
Sebt писал(а):
И все равно не могу себе представить как именно обращаясь к драйверу мы сможем запросить чтото конкретное сделать. Поидее ведь нужно заранее знать что он может. Или тут я не прав?

Именно нужно знать заранее.

Если это блочный драйвер то он должен поддерживать MSG_READ и MSG_WRITE. Если это видео драйвер то он должен поддерживать MSG_GET_MODE.
(SET сделать трудно)


Вам проще взять исходники MINIX'а и посмотреть как там это реализовано.

Sebt писал(а):
SII, я правильно понял вас, в том что. по вашему мнению. микроядра без написания так скажем специализированного компилятора не имеет смысла? Очень интересная информация, ибо крайне мало информации касательно микроядер, да и пишут их видимо редко.
А как реализуется обмен сообщениями? Я уловил вашу аналогию с почтовым ящиком, идея очень интересно звучит, мне уже чисто из любопытства интересно стало как это) Получается создается некий дополнительный буфер для каждого нового процесса?

Реализовать передачу сообщения это самое простое. Есть две функции GetMessage и SendMessage. Реализация примерно такая:

Приложение заполняет регистры сообщением. Вызывает int 7Fh

Код:
mov eax,GetMessage
mov ebx,0
mov ecx,0
int 7Fh


Процессор переключает стек приложения на стек ядра. Далее ядро обрабатывает регистры примерно так

Код:
// точка входа в ядро
procedure Int_7Fh;
asm
mov  DWord ptr [MainReg._EAX],eax
mov  DWord ptr [MainReg._ECX],ecx
mov  DWord ptr [MainReg._EDX],edx
mov  DWord ptr [MainReg._EBX],ebx
mov  DWord ptr [MainReg._ESI],esi
mov  DWord ptr [MainReg._EDI],edi

CALL OSService;

mov  eax, DWord ptr [MainReg._EAX]
mov  ecx, DWord ptr [MainReg._ECX]
mov  edx, DWord ptr [MainReg._EDX]
mov  ebx, DWord ptr [MainReg._EBX]
mov  esi, DWord ptr [MainReg._ESI]
mov  edi, DWord ptr [MainReg._EDI]

IRETD
end;


Приложение которое вызвало GetMessage как правило усыпляется пока в системе не появится ответ.
Приложения и драйвера в цикле крутят GetMessage и SetMessage.

В процедуре procedure Int_7Fh; я сохранял регистры, но так же можно сохранять стек. И вичитывать порцию данных из стека.
Так к примеру поступает виндоус и линукс при обработке DeviceIoControl

--------------------------
Есть куча вариантов по мимо очереди сообщений. Есть общая память, есть почтовые ящики, есть сокеты(WinSocks).
Но я бы вам посоветовал по мимо почтовых ящиков реализовать VFS. Создаете файл в памяти и пишети читаете в него привычными функциями VFSOpenFile() VFSReadData() VFSSeek() VFSCloseFile()


------------------

SII писал(а):
ну а нынешние компиляторы вовсю стремятся сделать любой ход хреновым; лично у меня стойкое ощущение, что Фортран и ПЛ/1 из ОС/360 конца 60-х/начала 70-х давали лучший код, чем современные компиляторы)

И трава была зеленее.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB