Що зупиняє збірку програми збірки операційної системи? [зачинено]


18

Перш за все, я початківець, тому, якщо це питання звучить нерозумно, будь ласка, вкажіть неправильні припущення.

Як я розумію, завданням операційної системи є управління апаратними засобами та програмним забезпеченням, яке працює на ОС. Крім того, наскільки я розумію, програми складання дозволяють практично безпосередньо контролювати обладнання. У програмі складання можна читати і записувати дані в регістри, а також читати і записувати дані в оперативну пам'ять.

Враховуючи цю свободу возитися з регістрами та оперативною пам’яттю, чи не вдасться програмами збірки впливати на операційну систему? Припустимо, ОС використовує регістр А для зберігання важливої ​​інформації, і припустимо, я запускаю зібрану програму на цій ОС. Якщо програма успішно записує мотлох в реєстр А, напевно це вплине на ОС.

Запитання:

  1. Чи можна возитися з регістром А способом, описаним вище?

  2. Якщо ні, що зупиняє програми монтажу змінювати регістри, використовувані ОС?


13
розумні програмісти ...
Tony Stewart Sunnyskyguy EE75

Зараз існує чимало архітектур комп'ютерів, які були в минулому, також було розроблено багато операційних систем. На яку архітектуру / ОС ви конкретно посилаєтесь? У деяких (старих) архітектурах не було можливості зупинити програму від того, що вона робила після запуску, це правильно. Але сучасне обладнання / ОС мають вбудовані апаратні засоби, які дають лише частину пам’яті для програми в «нормальному» режимі (не суперпользователь), і вона не може отримати доступ до пам’яті за межами цієї межі. Регістри можуть користуватися безкоштовно, оскільки ОС не зберігає корисну інформацію в регістрах, а лише в пам'яті / на диску.
cyclone125

2
У мікропроцесорі ваша програма працює в "режимі користувача", операційні системи працюють в "системному режимі". Якщо програма користувальницького режиму виконала інструкцію щодо зупинки, наприклад, машина не зупиниться. Зупинка буде захоплена, а операційна система викликається. Що стосується оперативної пам’яті, ОС створила б середовище для програми користувальницького режиму, щоб через апаратне забезпечення управління пам'яттю те, що програма користувача бачить як RAM-адреса X, насправді не була би RAM-адресою X.
Джордж Уайт,

1
@flux Я оновив свій коментар. Відповідь була б: немає "загальної" відповіді на ваше запитання, як є / були різні комп'ютерні архітектури / ОС. Це може бути по-різному.
cyclone125

2
... Давно я писав у сировинному кодовому коді. Е-ха !!! :-)
Рассел Макмахон

Відповіді:


33

Врешті-решт, усі програми є машинним кодом, незалежно від того, була мовою джерела асемблер чи мова високого рівня.

Важливим є те, що існують апаратні механізми, які обмежують те, що може зробити даний процес, у тому числі регістри «возитися з», які можуть впливати на інші програми або саму операційну систему.

Це почалося з простого розмежування режимів роботи "користувач" та "супервізор" і з того часу перетворилося в архітектуру безпеки з декількома "кільцями" привілеїв.


Ось дуже загальний приклад, щоб зробити його трохи більш конкретним:

  • У "режимі користувача" процес не може отримати доступ до пам'яті, яка не була призначена його ідентифікатору процесу. Пам'ять, призначена для інших процесів, і сама операційна система блокується. Сюди входять значення регістрів, які використовуються цими іншими процесами. Це забезпечується апаратним забезпеченням MMU.

  • Тому в "режимі користувача" процес не може отримати доступ до регістрів керування MMU.

  • І очевидно, що в "режимі користувача" процес не може змінити режим на "режим нагляду", за винятком дуже чітко визначеного механізму, який передбачає виклик функції операційної системи.

Операційна система отримує контроль, якщо процес намагається порушити будь-яке з цих правил. Як тільки це станеться, ОС може просто зупинити процес правопорушення, ніколи більше не виконуючи його інструкцій.


2
Якщо я правильно розумію, що ви говорите: Деякі процесори мають "режим користувача" та "режим нагляду". ОС працює в «режимі супервізора», і переводить процесор в «режим користувача» для запуску моєї вигаданої програми складання. У режимі "користувач" є регістри та RAM-адреси, до яких програма монтажу не може отримати доступ через обдуману розробку обладнання.
Флюс

3
В основному ця відповідь описує сучасні "i386-подібні" архітектури з MMU та захищеним режимом. Але для правдивості існує багато старих (i8080, MOS 6502 тощо), а також сучасних простіших (AVR, ARM Cortex-M тощо) архітектур, які не мають цих особливостей, і якщо використовується якась ОС (наприклад, стара CP / M, сучасні FreeRTOS, ChibiOS тощо) ніщо не може зупинити програму від того, що вона робить.
cyclone125

2
@Flux Архітектури i386 (і вище) надають детальну інформацію. Архітектура x86 має не лише адреси пам'яті, які можна захистити, але й адреси вводу-виводу. (Існують різні інструкції, які використовуються для доступу до пам'яті проти доступу вводу / виводу.) У i386 + є три адреси пам'яті. Сегментована / на основі селектора адреса використовує регістр селектору, який посилається на запис таблиці (GDT або LDT) для відображення пари в єдину 32-бітну лінійну адресу. Потім таблиці підказок перекладають 32-бітну лінійну адресу в 36-бітну фізичну адресу (P-II.) Захист існує на обох етапах перекладу.
jonk

4
@flux ваше резюме правильне. Програма в захищеній системі пам'яті з відповідною багатозадачною ОС не повинна мати змогу збивати систему з будь-яким потоком інструкцій. Навіть недійсні - вони потрапляють у спеціальний обробник.
pjc50

Незважаючи на те, що є кілька кілець (як мінімум, x86), дуже-дуже рідко можна використовувати будь-які більше двох.
ліс

10

У багатьох багатозадачних операційних системах використовується структура даних під назвою Блок управління процесом (PCB) для вирішення проблеми перезапису реєстру. Під час запуску коду ОС створює новий процес для його відстеження. На друкованій платі міститься інформація про ваш процес та простір, відведений для вмісту вмісту регістра. Скажімо, процес A в даний час працює на процесорі, і ваш код знаходиться в процесі B. Що відбувається, коли ви запускаєте код, відбувається щось подібне:

  1. Дані про стан процесу A (вміст реєстру, лічильник програми тощо) копіюються на його друковану плату.

  2. Дані про стан процесу B копіюються з його друкованої плати в регістри процесора

  3. Процес B працює на процесорі до тих пір, поки він не закінчиться або не буде попереджено

  4. Дані про стан процесу B копіюються назад на друковану плату

  5. Дані про стан процесу A копіюються назад в центральний процесор, і він продовжує працювати

Якщо операційна система працює як процес A, то ви можете побачити, як збереження її регістрів до запуску вашої програми, потім копіювання їх назад в центральний процесор після завершення роботи програми запобігає користувачеві програми не возитися з тим, що відбувається в інших процесах.

Щоб уникнути того, як користувацькі процеси записують дані ОС в пам'ять, більшість платформ використовують сегментацію пам'яті. В основному, використовуючи віртуальну пам'ять, адресний простір, який бачить процес, може бути відображений у будь-який довільний діапазон фізичних адрес. Поки фізичні простори пам’яті процесів не перетинаються, один процес не може перезаписати дані іншого.

Звичайно, різні ОС працюють на різні речі, тому це застосовуватиметься не у кожному випадку. Крім того, на більшості платформ процеси ОС працюють в іншому режимі, ніж користувацькі процеси, і там є деякі тонкощі.


4

Залежить від того, про яку платформу ви говорите.

  • На більш базовому процесорі процесор просто виконує всі вказівки, які програма каже йому виконувати.

  • На більш досконалому процесорі є (принаймні) два режими. В одному режимі процесор робить все, що програма йому каже. В іншому режимі сам процесор відмовляється виконувати певні вказівки.

Що зупиняє програму, яка розбиває всю систему? При першому типі процесора відповідь - "нічого". З базовим процесором одна негідна програма дійсно може розбити всю систему. Всі перші 8-бітні домашні комп'ютери та багато 16-бітних комп'ютерів потрапляють до цієї категорії.

На сучасному ПК процесор має апаратне забезпечення "захисту". В основному ОС працює в спеціальному режимі, що дозволяє їй робити що завгодно, тоді як звичайні програми працюють у режимі, коли процесор дозволить робити лише певні дії (виходячи з того, які налаштування ОС налаштувала на процесор). Такі речі, як лише доступ до певних регістрів або лише доступ до певних діапазонів пам'яті.

Очевидно, що дозволити одній програмі-шахрайці збити всю систему - це погано. (Також існують серйозні наслідки для безпеки, коли програма-шахрай дозволяє отримувати доступ до будь-яких даних.) Щоб цього уникнути, вам потрібно дві речі:

  1. Процесор, який фактично має апаратне забезпечення захисту (тобто його можна налаштувати для відмови від виконання певних інструкцій).

  2. ОС, яка фактично використовує ці засоби для захисту себе. (Недоцільно мати чіп із схемою захисту, якщо ОС його ніколи не використовує!)

Практично про будь-яку сучасну настільну ОС, яку ви можете назвати (Windows, Linux, Mac OS, BSD ...), це ОС у захищеному режимі, що працює на процесорі із захисним обладнанням. Якщо ви займаєтеся вбудованою розробкою на якомусь 8-бітному мікроконтролері, то, ймовірно, немає захисного обладнання. (Або будь-яка ОС, з цього питання ...)


1

В. Що зупиняє збір програми на збої операційної системи?

А. Нічого.

Однак багато дуже розумні програмісти протягом багатьох років дуже намагалися зробити це все складніше. На жаль, для кожного розумного програміста є багато, багато інших, хто між ними креативніший, амбітніший, а іноді і щасливіший, ніж розумний. Кожен раз, коли розумний програміст каже, що ніхто не повинен, хотів чи міг щось зробити, хтось там знайде спосіб це зробити. Microsoft Windows (як приклад) існує вже майже 35 років, і у нас все ще є BSoD (Blue Screens of Death), які є лише інструкціями, які розбивали операційну систему.

Почнемо з невеликої термінології. Все, що працює на комп’ютері, робить це в машинному коді. Біт, який читає натискання клавіш або рух вказівника миші, біт, який змінює колір пікселя на дисплеї або зчитує байт з файлу, і біт, який обчислює, чи потрапила ваша куля в бійці, або біт, який вирішує якщо заявку на вашу кредитну карту буде прийнято, всі виконуються як послідовність інструкцій машинного коду. Деякі завдання є настільки поширеними і виконуються так часто, що є сенс скласти інструкції, необхідні для їх виконання, і всі мають використовувати цю збірку. Купу цих завдань, які дозволяють або допомагають іншим користуватися комп'ютером, як правило, називають операційною системою, але між ними і будь-якими іншими програмами немає нічого принципово різного. Всі вони - лише послідовності інструкцій машинного коду.

Те, що робить операційні системи складнішими (і тому схильними до збоїв), полягає в тому, що вони повинні враховувати речі, про які зазвичай не потрібно думати. Візьмемо для прикладу найпростіші завдання. Я хочу написати повідомлення в кінець файлу. Мовою високого рівня ви б написали щось на зразок:

  with open("myFile.txt", "w+") as f:
      # do some really clever things
      f.write("Goodbye cruel world!")

Дозволяє ігнорувати всі подробиці про те, як доступні та змінені фізичні стани або як вони інтерпретуються як біти та байти або як ці байти передаються в пам'ять і процесор, а також довіряють, що все, що обробляється програмами, які надає ОС за лаштунками. Давайте просто подумаємо про те, як ви додасте до кінця файлу. 1) Дізнайтеся, де знаходиться кінець файлу, 2) щось запишіть у цьому місці. Що може піти не так? Власне, досить багато. Подумайте, що ще відбувається на комп’ютері, поки ви робите розумні речі. Якщо що-небудь, що робиться кимось іншим (включаючи саму операційну систему), будь-яким чином змінює файл, над яким ви працюєте, то ця справді проста робота раптом стає набагато складнішою. Файл довший, файл - коротший. Файлу вже немає. Диск повний,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.