ROS Newsletter76
Выпуск новостей ReactOS №76
Охота на призраков
Управление памятью в ReactOS всегда вызывало сомнения и недоверие у разработчиков ReactOS, поскольку в коде диспетчера памяти таится неопределённое количество скрытых ошибок. Они могут быть относительно безопасны при работе программ в пользовательском режиме, где возникновение критической ошибки практически невозможно. Однако, при работе программы в режиме ядра, эти же ошибки приводят к краху системы. Кэмерону Гутману (Cameron Gutman), Тимо Кройцеру (Timo Kreuzer) и Михаэлю Мартину (Michael Martin) удалось обнаружить причину нескольких из, пожалуй, наиболее серьезных утечек памяти. Михаэль столкнулся с проблемой при работе ROS на его модифицированной для отладки версии QEMU, но не мог найти строку кода, вызывающую повреждение памяти. В ходе исследований, Тимо нашёл код, который мог бы вызвать подобную ошибку, а Кэмерон помог проверить причину и протестировать исправляющий её патч.
Обнаруженная ими проблема находилась в механизме управления памятью, выделяемой для отдельных процессов. В большинстве современных операционных систем каждый процесс имеет так называемое виртуальное адресное пространство. Эти пространства заполняют весь диапазон адресов платформы, поэтому 32-битная платформа предоставляет возможность адресовать 4 Гб оперативной памяти. При этом, конечно, по большей части происходит управление виртуальной памятью, а не физической, однако и такого упрощённого объяснения будет вполне достаточно. Наличие таких адресных пространств позволяет процессам не беспокоиться об использовании памяти других процессов, по крайней мере, так должно быть. Всю сложную работу берёт на себя операционная система и аппаратное обеспечение компьютера. Поэтому, для обеспечения правильного доступа процессов к памяти, операционной системе необходимо вести учёт ресурсов и поддерживать дважды связанный список процессов. Связанные списки, в основном, содержат не только необходимые данные, но и ссылки на следующий элемент в списке. Дважды связанные списки же содержат ссылку и на следующий, и на предыдущий элементы.
Поскольку список процессов крайне важен для механизма управляения памятью операционной системы, он хранился в невыгружаемом пуле памяти (памяти режима ядра), который никогда не выгружается на жёсткий диск и всегда остаётся доступным в памяти. Так как невыгружаемый пул является крайне ценным и зачастую весьма ограниченным ресурсом операционной системы, он должен использоваться настолько экономно, насколько это вообще возможно. В коде ReactOS находилась ошибка, из-за которой при завершении процессов из списка не удалялись соответствующие им записи. Само по себе это не могло привести к повреждению данных даже в том случае, если бы данные в списках были удалены. Таким образом, эта область памяти расценивалась системой как не используемая и доступная для повторного использования. Но даже в этом случае проблема повлияет на работу системы только при создании нового процесса, так как в список должна быть добавлена новая запись. Это потребует изменения уже существующей, повреждённой записи, так как в неё необходимо добавить ссылку на создаваемую запись. Однако, если эта область памяти используется каким-либо другим процессом, то его данные будут изменены и повреждены. Так как невыгружаемый пул обычно используется для действительно критических частей данных, необходимых для обеспечения работоспособности системы, любое его повреждение приводит к крайне печальным результатам. Решение этой проблемы оказалось очень простым, достаточно было просто удалить недействительные записи, но именно отсутствие исправления для этой проблемы и становилось источником головной боли у разработчиков и тестеров.
PCI и компания
Операционная система, помимо всего прочего, должна предоставлять пользователю доступ к функциональным возможностям аппаратных средств, на которых она работает. Для этого операционной системе нужны драйвера, при помощи которых она сможет взаимодействовать с аппаратными средствами. Некоторые компоненты оборудования настолько критичны, что без драйвера для них компьютер практически невозможно нормально использовать, и сама по себе ОС будет почти бесполезна. Разработчики ReactOS всегда пытались поддержать базовый уровень функциональности, требующий как минимум поддержки расширений между программным обеспечением и аппаратными средствами, составляющими компьютер. Интерфейс периферийных компонентов (PCI) — одно из основных расширений, однако поддержка этого и других стандартов находилась настолько на примитивном уровне, что только несколько расширений использовались в их полном потенциале.
В ReactOS по большей части использовались устаревшие режимы взаимодействия с оборудованием, обычно используемые только для обеспечения обратной совместимости с устаревшим оборудованием, и до настоящего момента эти драйверы никогда не обновлялись. Они работали, хотя и с огромными потерями производительности относительно того, на что были способны аппаратные средства. Поэтому ничуть не удивительны проблемы с аппаратной совместимостью, с которыми сталкивались пользователи, обнаруживая, что ReactOS вообще не поддерживает требуемую функциональность. Часть функций является основными, такие, как поддержка IDE для жёстких дисков и ускоренный графический порт (AGP) для старых видеокарт. Другая часть функций специфична для ноутбуков, например, мосты PCI-PCI, используемые для док-станций, PCMCIA для различных карт беспроводной сети и прочих устройств расширения, а также функции управления электропитанием для поддержки аккумуляторов. Ещё одну часть функций можно отнести к категории функций, необходимых для серверов и рабочих станций, такие, как поддержка шины PCI с горячей заменой. Разработчики из команды ARM несколько месяцев работали над драйверами для поддержки этих функций и начали помещать их в репозиторий. Эти драйверы должны значительно улучшить совместимость и производительность ReactOS как на виртуальных машинах, так и на реальных аппаратных средствах. С их помощью ещё одна часть кода, необходимая для получения функциональной и полезной операционной системы, принимает законченный вид.
Newsletters | |
---|---|
30-39 | #30 • #31 • #32 • #33 • #34 • #35 • #36 • #37 • #38 • #39 |
40-49 | #40 • #41 • #42 • #43 • #44 • #45 • #46 • #47 • #48 • #49 |
50-59 | #50 • #51 • #52 • #53 • #54 • #55 • #56 • #57 • #58 • #59 |
60-69 | #60 • #61 • #62 • #63 • #64 • #65 • #66 • #67 • #68 • #69 |
70-79 | #70 • #71 • #72 • #73 • #74 • #75 • #76 • #77 • #78 • #79 |
80-89 | #80 • #81 • #82 • #83 • #84 • #85 • #86 • #87 • #88 • #89 |
90-99 | #90 • #91 • #92 • #93 • #94 • #95 • #96 • #97 • #98 • #99 |