Шрифт:
Таблица 19.4. Размеры страниц памяти для разных аппаратных платформ
Аппаратная платформа | Значение PAGE_SHIFT | Значение PAGE_SIZE |
---|---|---|
alpha | 13 | 8 Кбайт |
arm | 12, 14, 15 | 4 Кбайт, 16 Кбайт, 32 Кбайт |
cris | 13 | 8 Кбайт |
h8300 | 12 | 4 Кбайт |
i386 | 12 | 4 Кбайт |
ia64 | 12, 13, 14, 16 | 4 Кбайт, 8 Кбайт, 32 Кбайт, 64 Кбайт |
m68k | 12, 13 | 4 Кбайт, 8 Кбайт |
m86knommu | 12 | 4 Кбайт |
mips | 12 | 4 Кбайт |
mips64 | 12 | 4 Кбайт |
parisc | 12 | 4 Кбайт |
ppc | 12 | 4 Кбайт |
ppc64 | 12 | 4 Кбайт |
s390 | 12 | 4 Кбайт |
sh | 12 | 4 Кбайт |
spare | 12,13 | 4 Кбайт, 8 Кбайт |
sparc64 | 13 | 8 Кбайт |
v850 | 12 | 4 Кбайт |
x86_64 | 12 | 4 Кбайт |
При работе со страницами памяти необходимо использовать константу
Значение макроса
Порядок выполнения операций процессором
Вспомните из материала главы 9, "Средства синхронизации в ядре", что для различных аппаратных платформ процессоры в разной степени изменяют порядок выполнения программных инструкций. Для некоторых процессоров порядок выполнения операций строго соблюдается, запись данных в память и считывание данных из памяти выполняются в строго указанном в программе порядке. Другие процессоры имеют ослабленные требования к порядку выполнения операций считывания и записи данных и могут изменять порядок выполнения этих операций с целью оптимизации.
Если код зависит от порядка выполнения операций чтения-записи данных, то необходимо гарантировать, что даже процессор с самыми слабыми ограничениями на порядок выполнения чтения-записи будет выполнять эти операции в правильном порядке. Это делается с помощью соответствующих барьеров, таких как
Многопроцессорность, преемптивность и верхняя память
Может показаться неправильным включать поддержку симметричной многопроцессорности, возможность вытеснения процессов в режиме ядра и работу с верхней памятью в вопросы переносимости. В конце концов, это не особенности аппаратной платформы, которые влияют на операционную систему, а функции ядра Linux, которые по многом не зависят от аппаратной платформы. Тем не менее для этих функций существуют важные конфигурационные параметры, которые необходимо учитывать при разработке кода. Программировать всегда необходимо под SMP, с поддержкой преемптивности и с использованием верхней памяти, чтобы код был безопасным всегда, при любых конфигурациях. Необходимо всегда соблюдать следующие правила.
• Всегда необходимо учитывать, что код может выполняться на SMP-системе и использовать соответствующие блокировки.
• Всегда необходимо учитывать, что код может выполняться при включенной преемптивности ядра, поэтому необходимо всегда использовать необходимые блокировки и операции для управления преемптивностью.
• Всегда необходимо учитывать, что код может выполняться на системе с поддержкой верхней памяти (непостоянно отображаемая память) и при необходимости использовать функцию
Пару слов о переносимости
Если говорить коротко, то написание переносимого, ясного и красивого кода подразумевает следующие два момента.
• Код необходимо разрабатывать с учетом самого общего сценария: следует предполагать, что все, что может случиться, обязательно случится, и принять на этот счет все возможные меры.
• Всегда необходимо все подводить под наибольший общий знаменатель: нельзя полагаться на то, что будут доступны все возможности ядра, следует опираться только на минимум возможностей, которые доступны всем аппаратным платформам.
Написание переносимого кода требует строгого учета многих факторов: размер машинного слова, размеры типов данных, выравнивание в памяти, порядок байтов, размер страницы, изменение порядка операций процессора и т.д. В большинстве случаев при программировании ядра следует гарантировать, что типы данных используются правильно. Тем не менее время от времени все равно всплывают проблемы, связанные с особенностью той или другой аппаратной платформы. Важно понимать проблемы, связанные с переносимостью, и всегда писать четкий и переносимый код ядра.