Я думаю, что ответ SimonJ очень хороший, но я собираюсь опубликовать свой собственный, потому что из ваших комментариев видно, что вы не совсем понимаете вещи.
Во-первых, когда вы загружаете операционную систему, вы загружаете ядро в память и говорите «начните выполнение по адресу X». Ядро, этот код, по сути, просто программа, но, разумеется, больше ничего не загружается, поэтому, если он хочет что-то делать, ему нужно знать точные команды для конкретного оборудования, которое он к нему подключил.
Вам не нужно запускать ядро. Если вы знаете, как управлять всем подключенным оборудованием, вам это не нужно. Тем не менее, это было быстро понято, когда существовало много типов аппаратных средств, с которыми можно столкнуться, и наличие идентичного интерфейса в разных системах для программирования сделало бы код переносимым и, как правило, помогло бы выполнить работу быстрее.
Таким образом, функция ядра состоит в том, чтобы контролировать все оборудование, подключенное к системе, и представлять его в общем интерфейсе, называемом API (интерфейс прикладного программирования). Код для программ, работающих в системе, не взаимодействует напрямую с оборудованием. Они разговаривают с ядром. Таким образом, пользовательские программы не должны знать, как задать конкретному жесткому диску чтение сектора 0x213E или что-то еще, но ядро делает это.
Теперь описание кольца 3, приведенное в ответе SimonJ, показывает, как реализуется пользовательская область - с изолированными непривилегированными процессами с виртуальными частными адресными пространствами, которые не могут мешать друг другу, из-за преимуществ, которые он описывает.
Здесь также есть другой уровень сложности, а именно концепция разрешений. Большинство операционных систем имеют некоторую форму контроля доступа, при которой «администраторы» имеют полный контроль над системой, а «пользователи» имеют ограниченный набор параметров. Таким образом, запрос ядра на открытие файла, принадлежащего администратору, не должен выполняться при таком подходе. Пользователь, который запускает программу, является частью контекста программы, если вам нравится, и то, что программа может делать, ограничено тем, что может делать этот пользователь.
Большую часть того, чего вы могли бы достичь (если вы не собираетесь писать ядро), можно сделать в пользовательской среде как пользователь root / администратор, где ядро не отклоняет любые запросы API, сделанные к нему. Это все еще программа пользователя. Это все еще программа 3 кольца. Но для большинства (почти всех) применений этого достаточно. Многое может быть достигнуто как пользователь без полномочий root / администратор.
Это относится к интерпретатору Python и, соответственно, ко всему коду Python, выполняемому в этом интерпретаторе.
Давайте разберемся с некоторыми неопределенностями:
- Наименование
os
и sys
Я думаю, это потому, что это "системные" задачи (в отличие от urllib2
). Например, они дают вам возможность манипулировать и открывать файлы. Однако они проходят через интерпретатор python, который, в свою очередь, обращается к ядру.
- Я не знаю ни одной реализации Python в режиме ядра. Поэтому, насколько мне известно, нет никакого способа написать код на python, который будет работать в ядре (linux / windows).
- Существует два типа привилегированных: привилегированные с точки зрения аппаратного доступа и привилегированные с точки зрения системы контроля доступа, предоставляемой ядром. Python может запускаться от имени пользователя root / администратора (на самом деле в Linux многие инструменты администрирования написаны на python), поэтому в некотором смысле он может обращаться к привилегированному коду.
- Написание расширения C или управление приложением C в Python означало бы, что вы либо используете код, добавленный в интерпретатор (пользовательское пространство), либо управляете другим пользовательским приложением. Однако , если вы написали модуль ядра в C (Linux) или Driver в C (Windows), можно было бы загрузить этот драйвер и взаимодействовать с ним через API ядра из питон. Примером может быть создание записи / proc в C, а затем передача приложением python сообщений через чтение / запись в эту запись / proc (которую модуль ядра должен обработать с помощью обработчика записи / чтения. По сути, вы пишете код вы хотите работать в пространстве ядра и в основном добавлять / расширять API ядра одним из многих способов, чтобы ваша программа могла взаимодействовать с этим кодом.
- «Низкоуровневый» IO означает больший контроль над типом IO и тем, как вы получаете эти данные из операционной системы. Это низкий уровень по сравнению с функциями более высокого уровня, все еще работающими в Python, которые предоставляют более простые способы чтения файлов (удобство за счет контроля). Это сравнимо с разницей между
read()
звонками и fread()
или fscanf()
в C.
Предупреждение о работоспособности: написание модулей ядра, если вы ошиблись, в лучшем случае приведет к тому, что этот модуль будет загружен неправильно; в худшем случае ваша система будет паниковать / синий экран, и вам придется перезагрузиться.
Последний пункт о машинных инструкциях, я не могу ответить здесь. Это совершенно отдельный вопрос, и это зависит. Я уверен, что есть много инструментов, способных анализировать код, но я не являюсь реверс-инженером. Тем не менее, я знаю, что многие из этих инструментов (GDB, Valgrind), например. инструментам, которые подключаются к двоичному коду, не нужны модули ядра для своей работы.