Awk
раствор:
awk '{ printf "%d.%d.%d\n", substr($1,1,1), substr($1,2,3)/10, substr($1,5) }' file
substr(string, start [, length ])
-Возвращает длинную подстрокуlength
-символов -из string
, начиная с номера символа start
. Выход:
4.17.3
1.0.2
3.0.3
4.0.2
4.0.0
2.2.3
2.2.3
3.1.0
5.0.0
5.0.0
5.0.0
5.0.0
7.7.0
7.6.0
Если GNU awk
поддерживается, более короткий путь будет следующим:
awk -v FS="" '{ print $1, ($2$3$4)/10, $5 }' OFS='.' file
FS=""
-Если значением является пустая строка (""
), то каждый символ в записи становится отдельным полем. Когда я хочу это сделать, я использую структуру ftrace
. Начните с монтирования специальной файловой системы:
mount -t tracefs nodev /sys/kernel/tracing
(как корень; для всего этого вы должны стать root, вы все равно будете делать все как root, и проще иметь root shell, чем использоватьsudo
).
Затем перейдите в этот каталог:
cd /sys/kernel/tracing
Он содержит базовый README
краткий обзор. Чтобы исследовать вызовы функций, я использую трассировщик графика функций , function_graph
в available_tracers
. Определите интересующие вас функции, например ath9k_htc_tx
, и настройте их
echo ath9k_htc_tx > set_graph_function
Вы можете добавить другие функции, обязательно используйте >>
после первой функции. Вы можете увидеть сконфигурированные функции с помощью
cat set_graph_function
При записи в set_graph_function
функция проверяется на работающее ядро; если функция не может быть найдена, запись завершится ошибкой, поэтому вы сразу узнаете, не отследите ли вы что-либо.
После настройки функций включите трассировщик:
echo function_graph > current_tracer
, затем просмотрите файл trace
. Чтобы снова отключить трассировщик,
echo nop > current_tracer
или переверните tracing_on
, написав в него 0 или 1 (0, чтобы отключить трассировку, 1, чтобы повторно -включить ее ).
Основной вывод заключается в том, что драйверы соединяют верхний и нижний интерфейсы вместе. В случае ath9k_htc
нижний интерфейс — USB, верхний — сетевой стек.
Поток управления в значительной степени является конечным автоматом, который может реагировать на события, поступающие с обоих интерфейсов без какой-либо синхронизации, например, сетевой интерфейс вполне может уведомить драйвер о присоединении к группе многоадресной рассылки, и в то же время уведомление приходит из подсистемы USB о том, что устройство было извлечено --в многопроцессорных системах, эти события могут быть зарегистрированы на разных ЦП, и тогда драйвер будет введен одновременно.
Большинство драйверов не имеют контекста процесса или потока и управляются исключительно событиями -с циклом событий, внешним по отношению к драйверу, поэтому обычно вы видите множество небольших функций, обрабатывающих определенные события, пытающихся переслать их, делающих заметки. куда-то, если это не удается, и немедленно возвращаются.
Самый разумный способ визуализировать поток управления в типичном драйвере — нарисовать карту общих блокируемых ресурсов и указать, какие функции имеют к ним доступ, поскольку типичная линия связи заключается в блокировке списка, добавлении к нему данных и разблокировке. Если вы нарисуете функции, связанные с USB, с одной стороны, и функции, связанные с сетью, с другой стороны ресурсов, это должно дать вам наиболее четкую картину.