Устойчивость функции printk()
Устойчивость функции printk()
Одно из проверенных и часто используемых свойств функции printk() — это ее устойчивость. Функцию printk() можно вызывать практически в любое время и в любом месте ядра. Её можно вызывать из контекста прерывания и из контекста процесса. Её можно вызывать во время удержания блокировки. Её можно вызывать одновременно на нескольких процессорах и она не требует при этом удерживать какие-нибудь блокировки.
Эта функция очень устойчива, и это очень важно, потому что полезность функции printk() базируется на том факте, что она всегда доступна и всегда работает.
Неустойчивость функции printk()
Слабое место у функции printk() в плане устойчивости все же существует. Её нельзя использовать до некоторого момента при загрузки ядра, пока консоль еще не инициализирована. Действительно, если нет консоли, то куда будут выводится сообщения?
Обычно это не проблема, если не нужно выполнять отладку кода, который выполняется на очень ранних стадиях процесса загрузки (например, функции setup_arch(), которая выполняет инициализацию специфичную для аппаратной платформы). Отладка такого рода — настоящая задача: отсутствие каких-либо способов вывода сообщений, а только проблема в полном составе.
В таких ситуациях тоже есть некоторые обнадеживающие моменты, но их не много. Настоящие хакеры, которые работают с аппаратурой на таком низком уровне, для связи с внешним миром используют аппаратное обеспечение соответствующей платформы, которое всегда работает (например, последовательный порт). Поверьте, что у большинства людей такая работа не вызовет радости. Для одних аппаратных платформ такое решение работает, для других платформ (включая платформу i386) существуют заплаты кода, которые тоже позволяют сэкономить время.
Одно из решений проблемы — вариант функции printk(), который может выводить информацию на консоль на очень ранних стадиях процесса загрузки — early_printk(). Поведение этой функции аналогично функции printk(), за исключением имени и возможности работать на очень ранних стадиях загрузки. Однако, такое решение не переносимо, потому что не для всех поддерживаемых аппаратных платформ этот метод работы реализован. Если же он есть, то может сослужить хорошую службу.
Кроме ситуаций, когда необходимо выводить на консоль информацию на очень ранних стадиях загрузки системы, можно положиться на функцию printk(), которая работает практически всегда.