Чтение онлайн

на главную

Жанры

Разработка ядра Linux
Шрифт:

printk("Hello world! Строка: %s и целое число: %d\n",

 a_string, an_integer);

Одно важное отличие между

printf
и
printk
состоит в том, что в функции
printk
можно использовать флаг уровня вывода. Этот флаг используется программой
syslog
для того, чтобы определить, нужно ли показывать сообщение ядра. Вот пример использования уровня вывода:

printk(KERN_ERR "Это была ошибка !\n");

Функция

printk
будет использоваться на протяжении всей книги. В следующих главах приведено больше информации о функции
printk
.

Компилятор GNU

С

Как и все "уважающие себя" ядра Unix, ядро Linux написано на языке С. Может быть, это покажется неожиданным, но ядро Linux написано не на чистом языке С в стандарте ANSI С. Наоборот, где это возможно, разработчики ядра используют различные расширения языка, которые доступны с помощью средств компиляции gcc (GNU Compiler Collection — коллекция компиляторов GNU, в которой содержится компилятор С, используемый для компиляции ядра).

Разработчики ядра используют как расширения языка С ISO C99 [7] так и расширения GNU С. Эти изменения связывают ядро Linux с компилятором gcc, хотя современные компиляторы, такие как Intel С, имеют достаточную поддержку возможностей компилятора gcc для того, чтобы ими тоже можно было компилировать ядро Linux. В ядре не используются какие-либо особенные расширения стандарта C99, и кроме того, поскольку стандарт C99 является официальной редакцией языка С, эти расширения редко приводят к возникновению ошибок в других частях кода. Более интересные и, возможно, менее знакомые отклонения от стандарта языка ANSI С связаны с расширениями GNU С. Давайте рассмотрим некоторые наиболее интересные расширения, которые могут встретиться в программном коде ядра.

7

Стандарт ISO C99 — это последняя основная версия редакции стандарта ISO С. Редакция C99 содержит многочисленные улучшения предыдущей основной редакции этого стандарта. Стандарт ISO C99 вводит поименную инициализацию полей структур и тип

complex
.

Функции с подстановкой тела

Компилятор GNU С поддерживает функции с подстановкой тела (inline functions). Исполняемый код функции с подстановкой тела, как следует из названия, вставляется во все места программы, где указан вызов функции. Это позволяет избежать дополнительных затрат на вызов функции и возврат из функции (сохранение и восстановление регистров) и потенциально позволяет повысить уровень оптимизации, так как компилятор может оптимизировать код вызывающей и вызываемой функций вместе. Обратной стороной такой подстановки (ничто в этой жизни не дается даром) является увеличение объема кода, увеличение используемой памяти и уменьшение эффективности использования процессорного кэша инструкций. Разработчики ядра используют функции с подстановкой тела для небольших функций, критичных ко времени выполнения. Использовать подстановку тела для больших функций, особенно когда они вызываются больше одного раза или не слишком критичны ко времени выполнения, не рекомендуется.

Функции с подстановкой тела объявляются с помощью ключевых слов

static
и
inline
в декларации функции. Например,

static inline void dog(unsigned long tail_size);

Декларация функции должна быть описана перед любым ее вызовом, иначе подстановка тела не будет произведена. Стандартный прием — это размещение функций с подстановкой тела в заголовочных файлах. Поскольку функция объявляется как статическая (

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

В ядре использованию

функций с подстановкой тела следует отдавать преимущество по сравнению с использованием сложных макросов.

Встроенный ассемблер

Компилятор gcc С позволяет встраивать инструкции языка ассемблера в обычные функции языка С. Эта возможность, конечно, должна использоваться только в тех частях ядра, которые уникальны для определенной аппаратной платформы.

Для встраивания ассемблерного кода используется директива компилятора

asm
.

Ядро Linux написано на смеси языков ассемблера и С. Язык ассемблера используется в низкоуровневых подсистемах и на участках кода, где нужна большая скорость выполнения. Большая часть коду ядра написана на языке программирования С.

Аннотация ветвлений

Компилятор gnu С имеет встроенные директивы, позволяющие оптимизировать различные ветви условных операторов, которые наиболее или наименее вероятны. Компилятор использует эти директивы для соответственной оптимизации кода. В ядре эти директивы заключаются в макросы

likely
и
unlikely
, которые легко использовать. Например, если используется оператор
if
следующего вида:

if (foo) {

 /* ... */

}

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

/* предполагается, что значение переменной foo равно нулю ...*/

if (unlikely(foo)) {

 /* ... */

}

И наоборот, чтобы отметить этот путь выполнения как наиболее вероятный

/* предполагается, что значение переменной foo не равно нулю ...*/

if (likely(foo)) {

 /* ... * /

}

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

unlikely
и
likely
используются для проверки ошибок.

Отсутствие защиты памяти

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

NULL
и так далее, однако в ядре ставки значительно выше!

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

функции ядра
.

Нельзя просто использовать вычисления с плавающей точкой

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

Поделиться:
Популярные книги

На изломе чувств

Юнина Наталья
Любовные романы:
современные любовные романы
6.83
рейтинг книги
На изломе чувств

Подаренная чёрному дракону

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.07
рейтинг книги
Подаренная чёрному дракону

Совок 9

Агарев Вадим
9. Совок
Фантастика:
попаданцы
альтернативная история
7.50
рейтинг книги
Совок 9

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Без шансов

Семенов Павел
2. Пробуждение Системы
Фантастика:
боевая фантастика
рпг
постапокалипсис
5.00
рейтинг книги
Без шансов

Система Возвышения. Второй Том. Часть 1

Раздоров Николай
2. Система Возвышения
Фантастика:
фэнтези
7.92
рейтинг книги
Система Возвышения. Второй Том. Часть 1

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Возвращение

Кораблев Родион
5. Другая сторона
Фантастика:
боевая фантастика
6.23
рейтинг книги
Возвращение

Баоларг

Кораблев Родион
12. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Баоларг

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Вудворт Франциска
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Замуж второй раз, или Ещё посмотрим, кто из нас попал!

Измена. Испорченная свадьба

Данич Дина
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Измена. Испорченная свадьба

70 Рублей

Кожевников Павел
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
6.00
рейтинг книги
70 Рублей