diff options
Diffstat (limited to 'documentation/content/ru/articles/linux-emulation/_index.adoc')
| -rw-r--r-- | documentation/content/ru/articles/linux-emulation/_index.adoc | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/documentation/content/ru/articles/linux-emulation/_index.adoc b/documentation/content/ru/articles/linux-emulation/_index.adoc index 9d60209b00..322804579b 100644 --- a/documentation/content/ru/articles/linux-emulation/_index.adoc +++ b/documentation/content/ru/articles/linux-emulation/_index.adoc @@ -443,9 +443,9 @@ if (__predict_true(p->p_sysent != &elf_Linux(R)_sysvec)) * `fhold` - ссылается на обработчик файла [[md]] -== Слой эмуляции Linux(R) - машинно-зависимая часть +== Слой эмуляции Linux(R) - машинозависимая часть -В этом разделе рассматривается реализация слоя эмуляции Linux(R) в операционной системе FreeBSD. Сначала описывается машинно-зависимая часть, рассказывающая о том, как и где реализовано взаимодействие между пользовательским пространством и ядром. Рассматриваются системные вызовы, сигналы, ptrace, ловушки и исправление стека. Эта часть посвящена архитектуре i386, но написана в общем виде, поэтому другие архитектуры не должны сильно отличаться. Следующая часть — машинно-независимая часть Linuxulator. Этот раздел охватывает только i386 и обработку ELF. A.OUT устарел и не поддерживается. +В этом разделе рассматривается реализация слоя эмуляции Linux(R) в операционной системе FreeBSD. Сначала описывается машинозависимая часть, рассказывающая о том, как и где реализовано взаимодействие между пользовательским пространством и ядром. Рассматриваются системные вызовы, сигналы, ptrace, ловушки и исправление стека. Эта часть посвящена архитектуре i386, но написана в общем виде, поэтому другие архитектуры не должны сильно отличаться. Следующая часть — машинонезависимая часть Linuxulator. Этот раздел охватывает только i386 и обработку ELF. A.OUT устарел и не поддерживается. [[syscall-handling]] === Обработка системных вызовов @@ -576,9 +576,9 @@ translate_traps(int signal, int trap_code) Эмуляционный слой Linux(R) на i386 также поддерживает бинарные файлы Linux(R) в формате A.OUT. Почти всё, что описано в предыдущих разделах, должно быть реализовано для поддержки A.OUT (кроме перевода ловушек и отправки сигналов). Поддержка бинарных файлов A.OUT больше не поддерживается, в частности, эмуляция 2.6 с ними не работает, но это не вызывает никаких проблем, так как linux-base в портах, вероятно, вообще не поддерживает бинарные файлы A.OUT. Эта поддержка, скорее всего, будет удалена в будущем. Большая часть кода, необходимого для загрузки бинарных файлов Linux(R) A.OUT, находится в файле [.filename]#imgact_linux.c#. [[mi]] -== Слой эмуляции Linux(R) - машино-независимая часть +== Слой эмуляции Linux(R) - машинонезависимая часть -В этом разделе рассматривается машинно-независимая часть Linuxulator. Он охватывает инфраструктуру эмуляции, необходимую для эмуляции Linux(R) 2.6, реализацию thread local storage (TLS) (на i386) и фьютексы. Затем мы кратко обсуждаем некоторые системные вызовы. +В этом разделе рассматривается машинонезависимая часть Linuxulator. Он охватывает инфраструктуру эмуляции, необходимую для эмуляции Linux(R) 2.6, реализацию thread local storage (TLS) (на i386) и фьютексы. Затем мы кратко обсуждаем некоторые системные вызовы. [[nptl-desc]] === Описание NPTL @@ -713,7 +713,7 @@ mov %edx,%gs:0x10 [[tls-i386]] ===== i386 -Загрузка TLS для текущего потока происходит путем вызова `set_thread_area`, тогда как загрузка TLS для второго процесса в `clone` выполняется в отдельном блоке в `clone`. Эти две функции очень похожи. Единственное различие заключается в фактической загрузке сегмента GDT, которая происходит при следующем переключении контекста для вновь созданного процесса, в то время как `set_thread_area` должен загрузить его напрямую. Код в основном делает следующее. Он копирует дескриптор сегмента в формате Linux(R) из пользовательского пространства. Код проверяет номер дескриптора, но поскольку он различается между FreeBSD и Linux(R), мы немного имитируем его. Мы поддерживаем только индексы 6, 3 и -1. Число 6 — это оригинальный номер Linux(R), 3 — оригинальный номер FreeBSD, а -1 означает авто-выбор. Затем мы устанавливаем номер дескриптора на константу 3 и копируем его обратно в пользовательское пространство. Мы полагаемся на то, что процесс в пользовательском пространстве использует номер из дескриптора, но это работает в большинстве случаев (никогда не встречалось ситуации, когда это не срабатывало), так как процесс в пользовательском пространстве обычно передает 1. Затем мы преобразуем дескриптор из формата Linux(R) в машинно-зависимую форму (т.е. независимую от операционной системы) и копируем его в дескриптор сегмента, определенный FreeBSD. Наконец, мы можем загрузить его. Мы назначаем дескриптор PCB потока (блок управления процессом) и загружаем сегмент `%gs` с помощью `load_gs`. Эта загрузка должна выполняться в критической секции, чтобы ничто не могло нас прервать. Случай `CLONE_SETTLS` работает точно так же, только загрузка с помощью `load_gs` не выполняется. Сегмент, используемый для этого (сегмент номер 3), разделяется между процессами FreeBSD и Linux(R), поэтому слой эмуляции Linux(R) не добавляет накладных расходов по сравнению с обычным FreeBSD. +Загрузка TLS для текущего потока происходит путем вызова `set_thread_area`, тогда как загрузка TLS для второго процесса в `clone` выполняется в отдельном блоке в `clone`. Эти две функции очень похожи. Единственное различие заключается в фактической загрузке сегмента GDT, которая происходит при следующем переключении контекста для вновь созданного процесса, в то время как `set_thread_area` должен загрузить его напрямую. Код в основном делает следующее. Он копирует дескриптор сегмента в формате Linux(R) из пользовательского пространства. Код проверяет номер дескриптора, но поскольку он различается между FreeBSD и Linux(R), мы немного имитируем его. Мы поддерживаем только индексы 6, 3 и -1. Число 6 — это оригинальный номер Linux(R), 3 — оригинальный номер FreeBSD, а -1 означает авто-выбор. Затем мы устанавливаем номер дескриптора на константу 3 и копируем его обратно в пользовательское пространство. Мы полагаемся на то, что процесс в пользовательском пространстве использует номер из дескриптора, но это работает в большинстве случаев (никогда не встречалось ситуации, когда это не срабатывало), так как процесс в пользовательском пространстве обычно передает 1. Затем мы преобразуем дескриптор из формата Linux(R) в машинозависимую форму (т.е. независимую от операционной системы) и копируем его в дескриптор сегмента, определенный FreeBSD. Наконец, мы можем загрузить его. Мы назначаем дескриптор PCB потока (блок управления процессом) и загружаем сегмент `%gs` с помощью `load_gs`. Эта загрузка должна выполняться в критической секции, чтобы ничто не могло нас прервать. Случай `CLONE_SETTLS` работает точно так же, только загрузка с помощью `load_gs` не выполняется. Сегмент, используемый для этого (сегмент номер 3), разделяется между процессами FreeBSD и Linux(R), поэтому слой эмуляции Linux(R) не добавляет накладных расходов по сравнению с обычным FreeBSD. [[tls-amd64]] ===== amd64 |
