QEMU-tech.html или технология QEMU (перевод мой.)

Полезные советы и программы от пользователей нашего форума.

Модератор: Модераторы разделов

Аватара пользователя
polachok
Бывший модератор
Сообщения: 2199
Статус: главный форумный маргинал
ОС: gnu/linux

QEMU-tech.html или технология QEMU

Сообщение polachok »

Это часть 1. продолжение in progress
1. Введение

1.1 Возможности

QEMU это быстрый эмулятор процессора, использующий портируемый динамический транслятор.

QEMU имеет 2 режима работы:

* Полная эмуляция. В этом режиме QEMU эмулирует систему(обычно PC) полностью, включая процессор и периферию. Этот режим может использоваться для запуска другой ОС без перезагрузки или для отладки системного кода.

* Эмуляция на уровне пользователя(Только Linux). В этом режиме QEMU может запускать linux-программы, написанные под один процессор на другом. Этот режим может быть использован для запуска Wine(http://winehq.org) или чтобы упростить кросс-компиляцию и кросс-отладку.

Т.к. QEMU не требует модуля в ядре для работы, его безопасно и легко использовать.

Общие возможности QEMU:

* Эмуляция уровня пользователя или всей системы.

* Использование динамической трансляции на "родной" код для увеличения скорости.

* Работает на x86 и PowerPC хостах. Тестируется на архитектурах ARM, Sparc32, Alpha и S390.

* Поддержка самоизменяющегося кода.

* Аккуратная поддержка исключений

Виртуальный CPU это библиотека (libqemu) которая может использоваться в других проектах(пример использования в qemu/tests/qruncom.c)

Возможности пользовательского режима QEMU:

* Преобразователь системных вызовов Linux, включая большинство ioctl.

* Эмуляция clone() использует "родную" clone() процессора чтобы использовать диспетчер(планировщик) Linux для нитей(потоков).

* Аккуратная обработка сигналов с помощью преобразования сигналов хоста в сигналы объекта эмуляции.

Возможности полной эмуляции:

* QEMU также может использовать полный программный MMU для максимальной переносимости или использовать системный вызов mmap() хоста чтобы возпроизвести MMU объекта.

1.2 Эмуляция x86

Возможности эмуляции цели x86:

* Виртуальный х86 процессор поддерживает 16-ти и 32-х битную адресацию с сегментацией. Эмулируются LDT/GDT и IDT. Режим VM86 также поддерживается для запуска DOSEMU.

* Поддержка страниц(памяти?) размером более 4Кб в пользовательском режиме.

* QEMU может эмулировать себя на x86.

* Программа тестирования процессора для Linux находится в tests/test-i386. Она может быть использована для тестирования других виртуальных машин.

Текущие ограничения QEMU:

* Нет поддержки SSE/MMX (еще)
* Нет поддержки x86-64
* Системные вызовы IPC теряются.
* Права доступа и ограничения доступа к памяти не протестированы. К счастью, очень мало ОС использую их.
* На не-х86 хостах, doubleS используется вместо не стандартного 10 байтного long doubleS используемого на x86 для чисел с плавающей точкой для получения максимальной производительности.

1.3 Эмуляция ARM

* Полная эмуляция ARM 7.
* Поддержка NWFPE FPU включена в эмуляцию Linux.
* Возможен запуск большинства программ Linux для ARM.

1.4 Эмуляция PowerPC

* Полная эмуляция 32-х битного PowerPC, включая привелегированные инструкции, FPU и MMU.
* Возможен запуск большинста программ Linux для PowerPC

1.5 Эмуляция SPARC

* Поддержка SPARC V8, исключая инструкции FPU.
* Возможен запуск большинста программ Linux для SPARC.

2.QEMU изнутри.
2.1 QEMU в сравнении с другими эмуляторами.

Как bochs[3] QEMU эмулирует процессор х86. Но QEMU намного быстрее чем bochs так как он использует динамическую компиляцию. Bochs полностью привязан к эмуляции х86 РС, а QEMU может эмулировать несколько процессоров.

Как Valgrind[2], QEMU выполняет эмуляцию на уровне пользователя и использует динамическую трансляцию. Valgrind в большей cтепени отладчик памяти, а QEMU не поддерживает это. (QEMU может быть использован для выявления "скачкового" (bound) доступа к памяти как Valgrind, но не может отслеживать неинициализированные данные как Valgrind). Динамический транслятор Valgrind генерирует лучший код чем QEMU(например он производит register allocation) но он привязан к х86 и не поддерживает исключений и системной эмуляции.

ЕМ86 [4] наиболее близкий к пользовательскому QEMU проект (и QEMU еще использует его код, например загрузчик файлов ELF). ЕМ86 ограничен на alpha-хостах и использует проприетарный и медленный интерпретатор(из FX!32 Digital Win32 code translator [5]).

TWIN[6] это эмулятор Windows API типа Wine. Он менее аккуратен чем wine, но включает x86-интерпретатор защищенного режима чтобы запускать исполняемые файлы Windows. Такой подход обладает большим потенциалом т.к. большая часть Windows API выполняется nativly (вероятно имеется ввиду прямо на железе - прим. переводчика), но разработка его намного сложнее т.к. все структуры данных и параметры функций обмена между API и x86-кодом должны быть конвертированы.

User Mode Linux[7] был единственным решением до QEMU чтобы запустить ядро LInux как процесс без патчей ядра хоста. Но User Mode Linux требует много патчей для гостевого ядра, а QEMU использует обычный ядра Linux. Цена этого - QEMU работает медленнее.

Новый Plex86 [8] PC Virtualizer сделан в том же духе что и qemu-fast системный эмулятор. Он требует пропатченого ядра Linux для работы(невозможно запустить то же ядро на обычном PC), но патчей на самом деле немного. Так как это виртуализатор PC (никакой эмуляции кроме некоторых привелегированных интсрукций нет), он может быть потенциально быстрее QEMU. Другая сторона медали - требуется увесистый ( и потенциально небезопасный) патч ядра.

Коммерческие виртуализаторы PC (VMWare [9], VirtualPC [10], TwoOStwo [11]) бычтрее чем QEMU, но требуют специфичных, проприетарных и потенциально небезопасных драйверов для хоста. Более того, они не способны обеспечить точную эмуляцию как может симулятор.
2.2 Переносимая динамическая трансляция

QEMU - динамический транслятор. Когда он встречает кусок кода, он переводит его в набор инструкций хоста. Обычно динамические трансляторы очень увесисты и процессорно-зависимы. QEMU использует несколько ухищрений которые делают его относительно легко портируемым и простым, тем не менее достигая хорошей производительности.

Основополагающая идея состоит в разделении каждой x86 инструкции на несколько простых инструкций. Каждая простая инструкция осуществляется отрезком кода на Си.(см. target-i386/op.c). Затем утилита компиляции(dyngen) берет соответствующий объектный файл (op.o) чтобы породить генератор динамического кода, который объединяет простые инструкции в функции(см. op.h:dyngen_code()). В сущности, процесс подобен [1], но больше работы производится во время компиляции.

Ключевая идея получения оптимальной производительности в том что постоянные параметры могут быть переданы простым операциям. Для этой цели, простые ELF relocations генерируются с помощью GCC для каждого постоянного параметра. Затем, утилита(dyngen) может определить relocations и вызвать соответствующий код на Си, чтобы их решить во время сборки динамического кода.

Поэтому, QEMU не сложнее портировать чем динамический линкер(компоновщик)

2.3 Размещение(allocation) регистров

Т.к. QEMU использует фиксированные простые инструкции, эффективного размещения регистров быть не может. Ведь т.к. процессоры RISC имеют много регистров, большая часть состояния виртуального пройессора может быть размешена в регистрах без тяжелой процедуры размещения регистров.
polachok добавил в 06.01.2005 19:53
продолженеи(окончание):
2.4 Оптимизации кода условий

Хорошая эмуляция кода условий(регистр EFLAGS на х86) - критическая точка в для получения хорошей производительности. QEMU использует "ленивое" вычисление кода условий: вместо вычисления кода условия после каждой инструкции, он просто хранит один операнд(CC_SRC),результат(CC_DST) и тип операции (CC_OP).

CC_OP почти никогда не задается в генерируемом коде т.к. он известен во время трансляции.

Для повышения производительность генерируемыми простыми инструкциями выполняется ход назад(см. target-i386/translate.c:optimize_flags()). Когда может быть доказано что код условий не требуется для следующей инструкции, он не вычисляется.
2.5 Оптимизации состояния процессора

х86 процессор имеет много внутренних положений, которые изменяют метод оценки им инструкций. Чтобы достигнуть хорошей скорости, на фазе трансляции считается что некоторые значения состояния виртуального процессора не могут изменяться. Например, если сегменты SS,DS,и ES имеют нулевую базу, то транслятор даже не будет генерировать добавление для сегментной базы.
2.6 Кэш трансляций

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

После выполнения каждого базового блока QEMU использует симулируемый Program Counter (PC) и другие значения состояния процессора(как например базовое значениесегмента CS) чтобы найти следующий блок.

Чтобы ускорить наиболее общие случаи в которых может побывать симулируемый PC,QEMU может пропатчить базовый блок чтобы он сразу переходил к следующему.

Наиболее портируемый код использукт непрямые переходы. Непрямой переход делаетпроще изменение цели перехода. На некоторых архитектурах(таких как х86 и PowerPC) JUMP патчится таким образом что цепь блоков не имеет преимуществ.
2.8 Самоизменяющийся код и аннулирование транслируемого кода

Самоизменяющийся код особое требование в эмуляции x86, т.к. аннулирование кэша инструкций не сигнализируется приложением когда код изменяется.

Когда транслируемый код генерируется для базового блока, соответствующая страница памяти хоста защищается от записи,если она уже не только для чтения(с помощью системного вызова mprotect()). Если же производится запись, Linux выдает сигнал SEGV. QEMU затем аннулирует весь транслированный код на странице и позволяет доступ на запись.

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

Хотя преимущества вызовов mprotect() важны, большинство программ MSDOS могут быть эмулируемы на приемлимой скорости при помощи QEMU и DOSEMU.

Заметьте, QEMU также аннулирует страницы транслируемого кода, когда он выявляет, что память изменена с помощью mmap() или munmap().

Когда используется программный MMU, аннулирование кода наиболее эффективно6 если данная страница кода аннулируется слишком часто из-за записи на нее, тогдастроится битовая карта показывающая весь код страницы. Каждое сохранение на эту страницу проверяет требуется ли аннулирование кода. Аннулирование кода избегается только если данные изменились.
2.9 Поддержка исключений

Когда встречаются исключения(например деление на 0) используется longjump()

Хостовые обработчики SIGSEGV и SIGBUS используется для обработки недопустимого доступа к памяти. Точное состояние процессора может быть получено т.к. все регистры x86 хранится в фиксированных регистрах хоста. Симулируемый program counter основан на ретрансляции соответствующего базого блока и поиске точки исключения хостового program counter'a

Виртуальный процессор не может обнаружить точный регистр EFLAGS, т.к. в некоторых случаях он не подсчитывается для оптимизации кода. Это не особо важно, т.к. эмулируемый код может быть перезапущен в любом случае.
2.10 Эмуляция MMU

Для системной эмуляции QEMU использует системный вызов mmap() для эмуляции MMU нужного процессора. Это работает пока эмулируемая ОС не использует области памяти зарезервированные для хостовой ОС (например 0xc0000000 на Linux x86).

Чтобы можно было запускать любую ОС QEMU также поддерживает программный MMU. В этом режиме MMU транслирует виртуальный адрес в физический при каждом доступе к памяти. QEMU использует кэш адресов трансляции чтобы ускорить их.

Чтобы избежать уничтожение транслируемого кода каждый раз, когда MMU mappings изменяются, QEMU использует физически индексированный кэш трансляций. Это означает что каждый базовый блок индексируется своим физическим адресом.

Когда изменяются MMU mappings, происходит только cброс базовых блоков(т.к. базовый блок не может более переходить сразу к следующему).
2.11 Прерывания

Чтобы быть быстрее QEMU не проверяет каждый базовый блок если прерывание необработано. Вместо этого, пользователь асинхронно вызывает специфичную функцию чтобы сообщить что прерывание не обработано. Эта функция разрывает текущую цепь исполняющихся базовых блоков. Она гарантирует что выполнение скоро продолжится в главном цикле процессора. Затем главный цикл обрабатывает прерывание.
2.12 Эмуляция уровня пользователя
2.12.1 Трансляция системных вызовов Linux

QEMU включает в себя транслятор системных вызовов для Linux. Это значит чтопараметры системных вызовов конвертируются с исправлением endianness и 32/64 битissues(?). IOCTL конвертируются с помощью системы общих описаний.(см. ioctls.h и thunk.c).

QEMU поддерживает хостовый процессоры имеющий страницы более 4Кб. Он записывает все mappings, которые делает процесс и пытается эмулировать системный вызов mmap() если хостовый mmap() валится из-за "плохой" страницы.
2.12.2 Сигналы Linux

Нормальные сигналы и сигналы реального времени ставятся в очередь со своей информацией (siginfo_t) как это делается в ядре Linux. Затем делается запрос прерывания к виртуальному процессору. Когда он прерывается, один сигнал обрабатывается созданием frame stack в виртуальном процессоре как это делается в ядре Linux. Системный вызов sigreturn() эмулирует возвращение из виртуального обработчика сигналов.

Некоторые сигналы(напр. SIGALRM) приходят прямо с хоста. Другие синтезируются из исключений виртуального процессора, как SIGFPE когда производится деление на 0.(см.main.c:cpu_loop()).

Маска блокированного сигнала обрабатывается хостовым linux-ядром, поэтому большинство сигналов могут быть перенаправлены прямо хостовому ядру. Только системные вызовы sigaction() и sigreturn() нуждаются в полной эмуляции.(см. signal.c)
2.12.3 Системный вызов clone() и потоки

Системный вызов Linux clone() обычно используется для создания потоков. QEMU использует системный вызов clone() хоста так что один реальный поток создается для каждого эмулирующего потока. Один виртуальный процессор создается для каждого потока.

Заметьте, в настоящее время есть несколько проблем с блокировкой в QEMU. Например, кэш трансляций не защищен от повторного входа.
2.12.4 Самовиртуализация

QEMU может эмулировать себя. Хотя это не особо полезно, это важный тест мощи эмулятора.

Самовиртуализация не простая задача, т.к. могут быть конфликты адресов. QEMU решает эту проблему тем что он является исполняемым ELF-объектом как и ld-linux.so ELF(интрерпретатор ELF). Поэтому он может быть перемещен во время загрузки.(вероятно имеются ввиду адреса - прим. переводчика).

2.13 Bibliography

[1]
http://citeseer.nj.nec.com/piumarta98optimizing.html, Optimizing direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio Riccardi.

[2]
http://developer.kde.org/~sewardj/, Valgrind, an open-source memory debugger for x86-GNU/Linux, by Julian Seward.

[3]
http://bochs.sourceforge.net/, the Bochs IA-32 Emulator Project, by Kevin Lawton et al.

[4]
http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html, the EM86 x86 emulator on Alpha-Linux.

[5]
http://www.usenix.org/publications/library...ff/chernoff.pdf, DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton Chernoff and Ray Hookway.

[6]
http://www.willows.com/, Windows API library emulation from Willows Software.

[7]
http://user-mode-linux.sourceforge.net/, The User-mode Linux Kernel.

[8]
http://www.plex86.org/, The new Plex86 project.

[9]
http://www.vmware.com/, The VMWare PC virtualizer.

[10]
http://www.microsoft.com/windowsxp/virtualpc/, The VirtualPC PC virtualizer.

[11]
http://www.twoostwo.org/, The TwoOStwo PC virtualizer.
И немедленно выпил.
Спасибо сказали:

Аватара пользователя
magesor
Сообщения: 288
Статус: Человек-ништяк
ОС: есть.

Re: QEMU-tech.html или технология QEMU

Сообщение magesor »

Спасибо за инфу!
p.s.
Ух и какие ж недеццкия прям скажем тормоза (athlon 1600, 256 RAM DDR) у win2003, живущего в QEMU!!!
"Лишь две вещи поражают меня: звёздное небо надо мною и нравственный закон внутри меня." (Иммануил Кант)
Спасибо сказали:

Аватара пользователя
Ай-ай-ай
Сообщения: 257

Re: QEMU-tech.html или технология QEMU

Сообщение Ай-ай-ай »

Здорово ... спасибо.
"Я не червонец, чтобы нравиться всем!"
(с) Костя Кинчев ...
--------------------
Mandrake 10.1 PowerPack+; kernel 2.6.8.1; KDE 3.4.1
--------------------
"Пешу как хачу!" ... "Руки прочь от падонкафф!"
--------------------
http://www.livejournal.com/~_oparish_/
Спасибо сказали:

Аватара пользователя
zenwolf
Бывший модератор
Сообщения: 3138
Статус: Страшный и злой
ОС: Slackware..Salix..x86_64

Re: QEMU-tech.html или технология QEMU

Сообщение zenwolf »

(/bin/ladin @ Воскресенье, 16 Января 2005, 1:25) писал(а):Спасибо за инфу!
p.s.
Ух и какие ж недеццкия прям скажем тормоза (athlon 1600, 256 RAM DDR) у win2003, живущего в QEMU!!!

ясно дело будет тормозить -256мб минимально рекомендуемая для нормальной работы
2003-го ,а вы его батенька в эмуляторе :new_cool:
Quae videmus quo dependet vultus. (лат) - То, что мы видим, зависит от того, куда мы смотрим.
Спасибо сказали:

Аватара пользователя
alv
Бывший модератор
Сообщения: 7268
Статус: Пенсионер в законе
ОС: Cintu

Re: QEMU-tech.html или технология QEMU

Сообщение alv »

Спасибо, очень интересно. А версия для BSD у него есть?
И не хотители, когда все будет готово, поместить это дело на unix.ginras.ru
Спасибо сказали:

Аватара пользователя
polachok
Бывший модератор
Сообщения: 2199
Статус: главный форумный маргинал
ОС: gnu/linux

Re: QEMU-tech.html или технология QEMU

Сообщение polachok »

А версия для BSD у него есть?

да. я из портов юзал.
И не хотители, когда все будет готово, поместить это дело на unix.ginras.ru

хотел бы, с удовольствием. и, все, кстати, уже готово... это я после постинга первой части написал, а потом вторую просто добавил...
И немедленно выпил.
Спасибо сказали:

Аватара пользователя
alv
Бывший модератор
Сообщения: 7268
Статус: Пенсионер в законе
ОС: Cintu

Re: QEMU-tech.html или технология QEMU

Сообщение alv »

(polachok @ Воскресенье, 16 Января 2005, 13:29) писал(а):хотел бы, с удовольствием. и, все, кстати, уже готово... это я после постинга первой части написал, а потом вторую просто добавил...


Так размещаю? Не сегодня, конечно, но в ближайшие дни.
Спасибо сказали:

Аватара пользователя
polachok
Бывший модератор
Сообщения: 2199
Статус: главный форумный маргинал
ОС: gnu/linux

Re: QEMU-tech.html или технология QEMU

Сообщение polachok »

размещайте :) когда - не важно.
И немедленно выпил.
Спасибо сказали:

Аватара пользователя
zenwolf
Бывший модератор
Сообщения: 3138
Статус: Страшный и злой
ОС: Slackware..Salix..x86_64

Re: QEMU-tech.html или технология QEMU

Сообщение zenwolf »

вай чего только неподдерживает :
http://fabrice.bellard.free.fr/qemu/ossupport.htm
wolf_black добавил в 16.01.2005 17:03
хм скачал - заинтреговало скахем,буду пробовать - чего нибудь поставлю оригинальное
Quae videmus quo dependet vultus. (лат) - То, что мы видим, зависит от того, куда мы смотрим.
Спасибо сказали:

Аватара пользователя
magesor
Сообщения: 288
Статус: Человек-ништяк
ОС: есть.

Re: QEMU-tech.html или технология QEMU

Сообщение magesor »

(wolf_black @ Воскресенье, 16 Января 2005, 7:33) писал(а):
(/bin/ladin @ Воскресенье, 16 Января 2005, 1:25) писал(а):Спасибо за инфу!
p.s.
Ух и какие ж недеццкия прям скажем тормоза (athlon 1600, 256 RAM DDR) у win2003, живущего в QEMU!!!

ясно дело будет тормозить -256мб минимально рекомендуемая для нормальной работы
2003-го ,а вы его батенька в эмуляторе :new_cool:


Почему-то в wmware оно, казалось, побыстрее шуршало, к слову.
Но "быстрее" всего было в winxp+wmware. Раза так в 2 побыстрее.
"Лишь две вещи поражают меня: звёздное небо надо мною и нравственный закон внутри меня." (Иммануил Кант)
Спасибо сказали:

Аватара пользователя
polachok
Бывший модератор
Сообщения: 2199
Статус: главный форумный маргинал
ОС: gnu/linux

Re: QEMU-tech.html или технология QEMU

Сообщение polachok »

верно. это же полный ЭМУЛЯТОР. vmware - эмулятор ТОЛЬКО железных инструкций. а их меньше.
И немедленно выпил.
Спасибо сказали:

Аватара пользователя
bogus
Сообщения: 160

Re: QEMU-tech.html или технология QEMU

Сообщение bogus »

чего это он эмулирует кроме "железных" инструкций?
Как всякое несовершенное существо я могу ошибаться. Простите меня.
jabberId = foldl (flip (:)) [] "ur.rebbaj@43sugob"
Спасибо сказали:

Аватара пользователя
Acid Jack
Сообщения: 6

Re: QEMU-tech.html или технология QEMU

Сообщение Acid Jack »

Спасибо сказали:

Аватара пользователя
helicopter
Сообщения: 324
Статус: Комсомолец
ОС: Gentoo Linux

Re: QEMU-tech.html или технология QEMU

Сообщение helicopter »

Я cлышал есть какой-то модуль kqemu, который значительно ускоряет qemu.
Есть по нему инфа ?
Выбирая Linux, вы развиваете цивилизацию. Выбирая windows, вы набиваете кошелёк забугорному буржую...
Спасибо сказали:

virens
Сообщения: 125
ОС: Debian GNU/Linux

Re: QEMU-tech.html или технология QEMU

Сообщение virens »

helicopter писал(а):
27.07.2006 10:44
Я cлышал есть какой-то модуль kqemu, который значительно ускоряет qemu.
Есть по нему инфа ?

Есть, только сегодня кинул в блог, как ставить QEMU с ускорением. Здесь:
http://mydebianblog.blogspot.com/2006/07/qemu.html

Требуются заголовки ядра, gcc и несколько минут. С kqemu работает ощутиимо быстрее. Модуль не свободен, но бесплатен. QEMU при этом собирается из исходников. Всё написано в статье, будет интересно.

Acid Jack писал(а):
22.06.2006 14:25
<noindex>Документация пользователя эмулятора процессора QEMU</noindex> <noindex>mirror 1</noindex> <noindex>mirror 2</noindex>

лучше поздно, чем никогда

Большое спасибо за ссылки! Хотя это по большому счёту переведённый на руский язык man qemu, всё равно - замечательно. Как справочный материал - блеск!
Спасибо сказали:

Аватара пользователя
rolano
Сообщения: 845
Статус: еще один юзер FreeBSD
ОС: какая-то

Re: QEMU-tech.html или технология QEMU

Сообщение rolano »

заюзал этого зверя на FreeBSD 6.1/i386 c Целиком 2,53 и 256 метрами оперативки. Согласно рекомендации в одной из статей не ставил ускорящий модуль. Иксы - из прилагавшихся пакетов. Поставил Вин98 - тормозит очень существенно (ВМВарь не пробовал), зато прикольно.
Я знаю только то, что ничего не знаю ... потому и обречен вечно учиться.
Спасибо сказали:

virens
Сообщения: 125
ОС: Debian GNU/Linux

Re: QEMU-tech.html или технология QEMU

Сообщение virens »

rolano писал(а):
27.07.2006 14:49
Согласно рекомендации в одной из статей не ставил ускорящий модуль.

Убей автора этой статьи :angry: Маразм! БСД издёт в QEMU с ускорением kqemuна ура. Не идёт с ускорением только BEoS, Syllable и Reactos.
Спасибо сказали: