Сразу извиняюсь что в теме полный ноль. Вопрос такой: возможно ли технически спроецировать шину/порты/whatever железки, допустим видеокарту/видеопамять в пространство пользовательского процесса, полностью убрав обработку (к примеру) видео из ядра. Какие потенциальные недостатки у такого решения? Может быть, есть и ос, построенные на таком принципе? Или существуют какие-либо непреодолимые препятствия типа тайминга, синхронизации, дедлоков? Или современные процессоры позволяют доступ к железу исключительно из нулевого кольца?
Можно, конечно, только зачем? Процессору не принципиально, откуда ты стучишься к железу. Куда отобразишь память девайса - с такими правами и сможешь с ней общаться. С портами аналогично: выстави потоку EFLAGS.IOPL == 3, и сможешь стучать к портам из Ring3. В линуксе есть специальный сисколл iopl() для этого. На винде чуть посложнее, понадобится драйвер, который пропатчит IOPL. Просто непонятно, какой смысл. Чтобы что? В ядре работать с железками просто удобней: память ядра общая для всех процессов, а юзермод у каждого свой (если мы говорим о винде, линуксе и маке). А так, just 4 fun, конечно можно - отмапливай память железяки в свой процесс через условную MmMapIoSpaceEx + ремап в юзермод через IoAllocateMdl/MmProbeAndLockPages/MmMapLockedPagesSpecifyCache. Или даже проще: через ZwMapViewOfSection, отобразив \Device\PhysicalMemory с нужного адреса.
…которых не будет в юзермоде. Например, тебе нужен юзермодный видеодрайвер. Как процесс сможет им воспользоваться? Сейчас потоку надо уйти в ядро, где он попадёт в код видеодрайвера, и драйвер в контексте вызвавшего его потока будет общаться с девайсом. Отлично, убираем ядерную прослойку и уносим код драйвера в юзермодную дллку, а также мапим память девайса в наш графический процесс. Теперь процесс может напрямую читать и писать что-то в память видеокарты. Он может это сделать даже в обход драйвера, даже сделать это случайно. Кто-то ошибся в указателе и случайно записал в память видеокарты команду увеличить напряжение на двадцать вольт. Или, будь это юзермодный драйвер диска, баг в программе легко устроит тебе format C:. Оно тебе надо? Оно тебе не надо. Поэтому драйвера уносят в ядро, чтобы никто случайно или намеренно не мог свалить всю систему. А ещё юзермодный софт имеет свойство падать, а общение с аппаратурой зачастую неатомарно: чтобы сделать что-то, чаще всего нужно послать несколько команд. Что будет, если твоё приложение пошлёт три команды из пяти и упадёт? Девайс останется в неконсистентном состоянии, и лучше нам не проверять, чем это закончится.
Если формат с: или команду увеличить напряжение подаст ядерный драйвер, что меняется? Лишь то, что крашится вся система. Юзермодный софт не имеет свойства падать лишь по причине того что он юзермодный. Юзермодный софт падает по причине того что он хреново написан. Уже несколько лет как гугл и майкрософт много что из ядра перенесли в юзермод. Отказов стало сильно больше?
Но он не подаст, если в нём нет уязвимостей, через которые это смогут сделать. Других способов послать что-то девайсу у пользовательского софта нет. Открыв память девайсов и порты юзермоду, ты даёшь злоумышленнику карт-бланш: отныне никто не стоит между ним и железом. Отказ всей системы или даже повреждение железа в этом случае можно будет сделать в пару строчек, не имея никаких привилегий. Железо не знает ни про какие права доступа, кто угодно сможет прочитать или записать любой сектор на диске, утащив чувствительные данные, и никто не сможет этому помешать. К сожалению, я не знаю ни одного примера. Все драйвера, вся графика, абсолютно всё, что работает с железом во всех операционках, живёт в ядре и никогда не смотрит в юзермод.
Вообще-то, это вопрос из серии - зачем нужна ОС. Просто подумайте над смыслом слов: "разделяемый ресурс"
Нет, не была. Если под этим понимать "работы не только суперадмина, который заодно программист, понимает все что происходит в системе и имеет к ней персональный физически защищённый доступ", то вероятно да.
принципиальная разница в скорости - юзермод тормознутей, но если ядро затачивается лишь под один процесс - проблемы тормозов при переключение контекстов ужо нет.. глянь, например, юникерны - темка весьма перспективная - тот же видео редактор в форме юникерна будет просто гоночным мотоСИклем в сравнение с обычным десктопным.
В x86-32 из любого, https://www.cyberforum.ru/drivers-programming/thread656538-page2.html а в 64 что?
Часть способов подходит и для x64, но для этого ты уже должен иметь доступ в ядро. Дать юзермоду доступ к портам на современной 64х-битной винде без драйверов нельзя. Но если есть драйвер, можно пропатчить EFLAGS.IOPL в KTRAP_FRAME желаемого потока, и он получит в юзермоде доступ к портам и инструкциям cli/sti.
Да всем она была хороша. Если что, вопрос не про мсдос/Винду/Линукс/етс. Вопрос про принципиальную возможность на современном железе. Есть ли технические ограничения или вопрос лишь в программной реализации.
Встречный вопрос: зачем? Цели абстракции и изоляции, реализуемые операционной системой, это: (а) resource sharing/arbitration - то есть ресурс (видеокарту/"железо") ограничен в своих возможностях; при спроса к ресурса с нескольких процессов должен быть арбитр этого ресурса, который по заданым правилам будет распределять мощности этого ресурса среди n-ных потребителей (b) authoritative management - не уверен что правильную терминологию использую, но банально - если юзерский процесс упал, то система в целом должна стабильна с этим справиться и отставить ресурс ("железо") в рабочем состояние. Традиционно эту функцию реализовало разделение на ядро (ring-0) и "юзерские процессы" (ring-3). Ядро следит и отвечает за стабильность системы, изолирую потенциально дефектные части системы с свою среду (ring-3). Эти слои накладывают свою стоимость (с точки зрение производительности).