Нарыла свою старую статью о приключениях одного моего другана. На сайте HP очень распространена рекомендация обновить прошивку. Вот, почитайте, что после этого бывает.
У меня есть друг Санёк. Где-то в 2014-15 году он купил ноут фирмы HP: Elitebook 840 G5 с конфигурацией intel core i5-8250U, 4 ядра по 1.6 GHz с разгоном до 3.4 в режиме турбо. Он тогда стоил около 100 килорублей. Я помню, когда он его только купил, то рассказывал, что с выключенным turbo boost ноут не загружается. Вообще, когда я ещё сидела на винде, то много читала о том, что у HP проблемы с драйверами и прошивкой. Если у вас не винда, проблемы усугубляются, в чем Санёк убедился лично.
Собственно этот turbo boost и стал причиной всей свистопляски. Это интеловская технология: при выполнении задач, не расходующих процессор, он работает с базовой тактовой частотой, а при необходимости одно ядро разгоняется в случае Санька больше чем в 2 раза. Короче, через месяц после окончания гарантийного срока у Саниного ноута вздулась батарея. Оказалось, что он пользовался турбо, а в его старой прошивке не было "умного" управления АКБ - это когда она заряжается до 80% и разряжается до 20%. Режим турбо требует наличия батареи, так как блок питания ноутбука не рассчитан на такую мощность, и поэтому получается, что батарея постоянно слегка разряжается, потом автоматически начинает заряжаться и быстро дохнет из-за большого количества циклов зарядки.
Купил Саня АКБ русско-китайского производства, вставил её, ноут заработал, но перед загрузкой системы прошивка каждый раз высирала сообщение о том, что "у вас левая батарея, это может повлечь ядерный взрыв и эпидемию чумы". Санька это сообщение разозлило, и он полез на форум HP. Оказалось, что там сидят дебилы типа как в ростелекоме на первой линии: им уже задали этот вопрос, и они ответили, что надо отключить уведомления в винде. Автор вопроса напомнил придуркам, что сообщение появляется до загрузки системы, после чего его просто проигнорили. Саня сказал, что они вообще если встречают вопрос, на который не могут ответить, то шлют на хуй без церемоний.
Тогда Санек решил проявить смелость и обновить прошивку. Нет, он не лох и не чайник, он системный архитектор. Просто никогда раньше не делал этого, решил попробовать (на свою ж...). Он решил делать это из Винды. У него дуалбут: искоробочная Виндос 10 и Генту. Виндой он пользуется только для игр, поэтому три года её не обновлял. Чтобы найти нужную прошивку, он обновил систему, и она затерла ему первичный загрузчик GRUB. Он признался, что у него долго горела жопа: сука, я же не устанавливал её, а только обновил! Так как он занимается этим не каждый день, ему пришлось читать документацию, как записать grub обратно, скачивать system rescue cd и все это делать. Протрахался около двух часов. Это было только начало. Но наконец все было сделано, и винда в опциональных обновлениях предложила ему обновить EFI.
После этой процедуры сообщение о батарее не исчезло, зато тачпад - Саня предпочитает его мыши - стал глючить, пролистывая две страницы вместо одной. Этот глюк проявлялся только в генту, но не в винде. Но это ещё не самое хреновое. Оказалось, что кулер на процессоре перестал разгоняться до полных оборотов. Естественно, чип стал греться как не в себя и в генту, и в винде. Саня решил откатить прошивку назад, но с версии, предшествующей его версии, откат стал невозможен. Он узнал об этом из документации на сайте HP, а не из сообщения, которое должно было его об этом предупредить перед обновлением. Кстати, он очень похвалил официальную документацию на их сайте: сказал, что там черт ногу сломает, хрен разберешься. Тогда он решил обновиться до следующей версии, которую нарыл на сайте. В общем, потрахавшись ещё, он обновился, и там, насколько я помню, как раз оказалось умное управление батареей. Ну хоть что-то.
Поимев секс, Санёк решил проблему с тачпадом, а с вентилятором ничего не вышло. Он попробовал thermald, но тот ему не помог, что в принципе логично - прошивка же не работает, что система может. В результате он просто выставил порог, выше которого частота не должна подниматься, и сидит теперь на обгрызанном процессоре.
Итак, в результате обновления прошивки Саня приобрел умное управление АКБ, которое увеличит срок службы последней, если пользоваться режимом турбо, без которого ноут не загружается. При этом у него перестал раскручиваться на полную мощность вентилятор. Сообщение о левой батарее не исчезло. Также он просрал десять дней своего времени и кучу нервов. Давать оценку результату я предоставлю читателям.
Saturday, February 14, 2026
Обновление прошивки на HP Elitebook 840 G5
Friday, December 19, 2025
Процесс загрузки FreeBSD
Оригинал: https://klarasystems.com/articles/the-freebsd-boot-process/
В этой статье изучается процесс загрузки FreeBSD. Он надёжен и хорошо продуман, но слегка различается в зависимости от архитектуры системы, файловой системы (UFS или ZFS), схемы разметки диска (GPT или MBR) и интерфейса прошивки, управляющего загрузкой (UEFI или BIOS/CSM).
● BIOS
BIOS также известен как режим CSM или legacy. Это старый механизм загрузки 16-битных систем, который до сих пор поддерживается на многих компьютерах. Он подходит для загрузки FreeBSD, хотя будет чуть медленней UEFI и не поддерживает загрузку с устройств NVMe. Режим BIOS поддерживает разметки MBR и более современную GPT, а также слайсы Freebsd.
● UEFI
Все современные системы архитектуры amd64 поддерживают режим загрузки UEFI; также многие из них поддерживают устаревший режим BIOS ─ некоторые даже предлагают установить один из них основным, а второй в качестве запасного, если первый метод не сработает.
Также режим UEFI доступен на многих системах с архитектурой arm64 ─ его поддержка требуется для сертификата ServerReady ARM.
Некоторые системы arm64 и riscv/riscv64 поддерживают загрузку с помощью U-Boot вместо загрузки с помощью UEFI ─ FreeBSD поддерживает оба метода. Системы архитектуры RISC-V также можно загружать с помощью загрузчика OpenSBI, заменившего BBL(Berkley Boot Loader) из проекта FreeBSD. В данный момент команда FreeBSD работает над реализацией поддержки UEFI в системах RISC-V.
● Процесс загрузки Freebsd
Этот процесс бывает довольно сложным и включает в себя множество частей, которые сложно отличить друг от друга. Чтобы облегчить понимание, мы разбили статью на два раздела. В первом рассматривается часть загрузки, предшествующая запуску программы loader(8), которая отображает знаменитое "меню с Бисти"; второй посвящен тому, что происходит после того, как loader загрузит выбранное ядро системы.
▪ Стадии загрузки до активации загрузчика Freebsd ─ программы loader(8)
К этапу загрузки ядра Freebsd и передачи управления загрузкой процессу PID 1 ─ то есть системе init(8) ─ можно прийти разными путями в зависимости от архитектуры системы, метода загрузки, схемы разметки и файловой системы.
Прежде чем вникать в детали каждого режима загрузки, давайте схематично разобьем их на стадии:
BIOS/ MBR/UFS
+-> MBR from 'Boot Device' BIOS disk | MBR
+-> boot0 | STAGE 0
+-> boot1 | STAGE 1
+-> boot2 | STAGE 2
+-> loader | STAGE 3
+-> kernel | KERNEL
+-> init | INIT
BIOS/ MBR/ZFS
+-> MBR from 'Boot Device' BIOS disk | MBR
+-> boot0 | STAGE 0
+-> boot1 | STAGE 1
+-> zfsboot | STAGE 2
+-> zfsloader | STAGE 3
+-> kernel | KERNEL
+-> init | INIT
BIOS/ GPT/UFS
+-> GPT from 'Boot Device' BIOS disk | GPT
+-> pmbr | STAGE 0
+-> gptboot | STAGE 1 + STAGE 2
+-> loader | STAGE 3
+-> kernel | KERNEL
+-> init | INIT
BIOS/ GPT/ZFS
+-> GPT from 'Boot Device' BIOS disk | GPT
+-> pmbr | STAGE 0
+-> gptzfsboot | STAGE 1 + STAGE 2
+-> zfsloader (analogous to loader) | STAGE 3
+-> kernel | KERNEL
+-> init | INIT
UEFI/GPT/MBR/UFS/ZFS
+-> GPT/MBR from 'Boot Device' BIOS disk | GPT/MBR
+-> UEFI | STAGE 0
+-> boot1.efi (/efi/boot/boot${ARCH}.efi) | STAGE 1 + STAGE 2
+-> loader.efi | STAGE 3
+-> kernel | KERNEL
+-> init | INIT
UEFI/GPT/MBR/UFS/ZFS (13.0 and later)
+-> GPT/MBR from 'Boot Device' BIOS disk | GPT/MBR
+-> UEFI | STAGE 0
+-> loader.efi (/efi/FreeBSD/loader.efi) | STAGE 1-3
+-> kernel | KERNEL
+-> init | INIT
Переменная ARCH, в зависимости от вашей системы, может принимать одно из значений: x86 - x64 - arm - aa64.
Теперь, когда у вас есть общее представление о процессе загрузки, давайте рассмотрим каждый режим подробно.
▪ BIOS/Legacy, MBR и UFS
Использование таблицы разделов MBR и файловой системы UFS ─ самый старый метод загрузки FreeBSD. Допустим, ваше загрузочное устройство ─ диск с интерфейсом sata: /dev/ada0. На нём есть один основной раздел MBR (в терминах FreeBSD он называется слайс), который система видит как /dev/ada0s1. На этот слайс надо будет установить флаг активного (загрузочного) раздела. Внутри слайса вы увидите разделы (партиции) BSD, созданные утилитой bsdlabel(8). Корневой раздел, с которого будет производиться чтение в процессе загрузки, обозначен как /dev/ada0s1a.
Stage 0:
Из-за ограничений на размер файла загрузчика, накладываемых BIOS+MBR, загрузчик делится на стадии. BIOS загружает в память для исполнения первый сектор диска. Это называется нулевой стадией ─ stage 0. Нулевая стадия использует файл /boot/boot0, в котором записано 446 байт кода на ассемблере, а оставшиеся 66 байт (512-446) первого сектора содержат таблицу разделов (именно поэтому в ней может быть только 4 пункта) и сигнатуру. После загрузки в память программа, которая 446 байт, анализирует таблицу разделов и отображает меню загрузки на основании кода типа раздела, считанного из таблицы. Например:
F1 FreeBSD
F2 Win
Default: F1
Вместо файла /boot/boot0 можно использовать /boot/boot0sio ─ в этом случае меню также будет выведено на последовательную консоль. Но если на вашей машине нет последовательной консоли, она может зависнуть в процессе загрузки, поэтому данный файл не используется по умолчанию.
Stage 1:
Следующий этап загрузки ─ считывание и выполнение файла /boot/boot1 с первого сектора выбранного первичного раздела (слайса) ─ это называется Stage 1. Как правило, на этом этапе выполняются два файла: /boot/boot1 (512 байт) и /boot/boot2 (7680 байт). Файл /boot/boot2 занимает первые шестнадцать секторов по 512 байт, которые UFS не использует.
Главная задача boot1 ─ загрузка следующей стадии загрузчика, которая имеет более сложный код, чем первая стадия. Этот код загружает сервер BTX, после чего тот загружает свой клиент boot2, а затем ещё один клиент под названием loader. После этого мы переходим на вторую стадию.
Stage 2:
boot 2 задаёт и инициализирует важную структуру данных bootinfo и передаёт её загрузчику, а затем ─ ядру FreeBSD, но об этом позже. boot 2 ─ это маленькая программа, которая имеет базовую информацию о файловой системе UFS, достаточную, чтобы найти файлы /boot/loader и /boot/kernel ─ учитывая объём кода (7680 байт), это весьма впечатляет.
Stage 3:
Запускается loader, который ищет ядро и загружает его. Как уже было сказано, loader также является клиентом BTX. Считываются и загружаются конфигурационные файлы /boot/loader.rc и /boot/loader.conf. Основная задача программы loader - загрузка ядра FreeBSD; loader позволяет выбрать одно из нескольких ядер. После загрузки ядра в память начинается его инициализация.
▪ BIOS/Legacy, MBR и ZFS
Схема загрузки ZFS с раздела MBR слегка отличается. На нулевой стадии (Stage 0) boot0 загружает другой файл boot1. Затем boot1 находит файл zfsboot ─ аналог boot2 ─ размером 64 КiB по смещению 1 Mib на разделе ZFS в предопределенном пустом месте файловой системы.
Это означает, что на этапах Stage 1 и Stage 2 соответственно код zfsboot распознает файловую систему ZFS и загружает zfsloader. zfsloader выводит интерактивное меню, аналогичное тому, которое выдает loader для системы UFS. Точно так же, как и loader, zfsloader после этого загружает ядро и остальную часть системы FreeBSD.
Этап, на котором zfsloader уже загружен и работает ─ это Stage 3. На этой стадии можно выбрать, какой ZFS Boot Environment загружать.
▪ BIOS/Legacy, GPT и UFS
Теперь давайте рассмотрим чуть более современный процесс загрузки с использованием таблицы разделов GPT, но в режиме загрузки BIOS (Legacy, CSM). Хотя диск размечен с использованием таблицы GPT, он все равно содержит защитную загрузочную запись ─ Protective MBR или, сокращенно, pmbr. Она нужна для того, чтобы операционные системы, не поддерживающие схему GPT, не определяли диск как неразмеченный.
pmbr загружает FreeBSD тем же способом, что и MBR ─ считывается один сектор размером 512 байт и выполняется код из него. Это можно назвать нулевой стадией ─ Stage 0.
Специальный загрузочный раздел GPT (его тип freebsd-boot) содержит код других стадий загрузчика: gptldr ─ аналог boot1 ─ и gptboot вместо boot2. Это будут соответственно Stage 1 и Stage 2.
pmbr находит этот загрузочный раздел и выполняет код, содержащийся в нём. Для файловой системы UFS используется файл gptboot. Как и раньше, первый этап (Stage 1) представляет собой программу на ассемблере размером 512 байт, которая только загружает и выполняет Stage 2. gptboot содержит код, который больше по размеру и позволяет обращаться к UFS, а также (опционально) понимает шифрование GELI, Этот код умеет находить загрузчик на разделе с файловой системой UFS и запускать его.
На стадии Stage 3 loader загружен и работает, можно выбрать, какое ядро загружать.
▪ BIOS/Legacy, GPT и ZFS
Загрузка с GPT и файловой системой ZFS во многом похожа на схему с GPT и UFS2. Сначала pmbr загружает систему FreeBSD, выполняя код из первого сектора размером 512 байт ─ как и в случае MBR. Этот этап можно назвать Stage 0.
Специальный загрузочный раздел GPT (тип freebsd-boot) содержит код других стадий загрузчика: gptldr ─ аналог boot1 ─ и zfsboot вместо boot2. Это Stage 1 и Stage 2.
pmbr считывает и выполняет код из этого раздела. Для ФС ZFS используется файл gptzfsboot, который содержит информацию о ZFS и ─ опционально ─ о GELI и может расшифровать, загрузить в память и запустить zfsloader из набора данных ZFS, созданного по умолчанию.
Когда zfsloader загружен и работает, начинается Stage 3 и можно выбрать, какую среду загрузки и какое ядро загружать.
▪ UEFI, GPT/MBR и UFS/ZFS
А теперь поговорим о "новейшем" способе загрузки FreeBSD ─ с помощью Unified Extensible Firmware Interface, (UEFI). UEFI быстрее, чем метод BIOS, поскольку переходит в 64-разрядный режим, как только это становится возможным.
Немного предыстории: первой реализацией интерфейса был Intel EFI для архитектуры Itanium (IA64). Затем эту разработку "унифицировали" и перенесли на другие архитектуры ─ отсюда и "Unified" в начале названия. Разумеется, это очень сокращённая версия истории прошивки: кроличья нора значительно глубже, ─ но в данном случае этого достаточно.
FreeBSD прекрасно поддерживает режим загрузки UEFI. Разумеется, как и в случае других способов загрузки, процесс делится на стадии. Эти стадии практически не зависят от таблицы разделов на диске ─ GPT или MBR.
На этапе Stage 0 после включения питания запускается интерфейс прошивки UEFI и ищет загрузчик операционной системы на разделе EFI File System Partition (ESP), отформатированном в FAT32. UUID системного раздела C12A7328-F81F-11D2-BA4B-00A0C93EC93B.
В зависимости от архитектуры файл загрузчика может называться следующим образом:
ARCH WIDE PATH
i386 32bit /efi/boot/bootx86.efi
amd64 64bit /efi/boot/bootx64.efi
arm 32bit /efi/boot/bootarm.efi
arm64 64bit /efi/boot/bootaa64.efi
По умолчанию во FreeBSD файл boot1.efi установлен под именем bootx64.efi. Его исполнение означает, что мы находимся на этапе Stage 1 или Stage 2.
Для определения корневой файловой системы, с которой будет загружаться FreeBSD, файл boot1.efi использует такую последовательность:
- Поиск загрузочных пулов для ZFS
- Поиск загрузочных разделов для UFS
Раздел распознаётся как загрузочный, если boot1.efi может загрузить с него loader.efi. Если на одном устройстве есть как раздел UFS, так и ZFS, то предпочтение отдаётся ZFS. После того как UEFI исполнит код файла bootx64.efi (который на самом деле boot1.efi), начинается этап Stage 3 и загружается loader.efi, который позволяет выбрать среду загрузки и ядро.
После того, как среда загрузки и ядро будут выбраны, loader.efi загрузит ядро FreeBSD.
● Ядро и многопользовательский режим
Прежде чем загрузить выбранное ядро, loader считывает и загружает параметры из файла /boot/device.hints. После выбора ядра и/или среды загрузки loader запускает ядро, которое начинает проверку наличия и инициализацию устройств.
Затем ядро передаёт управление процессу /sbin/init (PID 1), который монтирует файловые системы. init(8) также занимается другими вещами ─ такими как виртуальные консоли, найденные в файле ttys(5), ─ и запускает процессы getty(8), которые, в свою очередь, инициализируют команды login(1).
Закончив с этим, init(8) продолжает процесс загрузки в многопользовательский режим, после чего начинает конфигурацию системных служб FreeBSD ─ rc(8). Параметры системных служб по умолчанию считываются из файла /etc/defaults/rc.conf, а специфичные для системы данные ─ из файла /etc/rc.conf.
Затем монтируются файловые системы из /etc/fstab и выдаются адреса сетевым интерфейсам. И наконец запускаются сервисы и демоны с помощью стартовых скриптов из файлов /etc/rc.d и /usr/local/etc/rc.d. rcorder(8) гарантирует правильный порядок их запуска.
● nextboot(8)
Во FreeBSD есть утилита nextboot(8), которая позволяет загрузить определенное ядро, указав флаги к нему, только один раз ─ при следующей загрузке.
Это достигается тем, что loader(8) считывает информацию о ядре из файла /boot/nextboot.conf при его наличии. При перезагрузке машины nextboot.conf автоматически удаляется и система возвращается к предыдущей "постоянной" конфигурации.
Для файловых систем ZFS nextboot хранит метаданные в специально отведенном поле метки пула ZFS, поскольку загрузчик более ранней стадии не может записывать в сам пул. Метаданные nextboot стираются сразу после считывания и поэтому влияют только на один процесс загрузки после их записи.
Чтобы один раз загрузить ядро FreeBSD под названием CUSTOM, введите следующую команду:
# nextboot -k CUSTOM
Если надо загрузить тестовое ядро TEST в однопользовательском режиме, введите команду:
# nextboot -o "-s" -k TEST
Следующая команда удаляет все существующие конфигурации nextboot(8):
# nextboot -D
● Флаги загрузки bootme/bootonce/bootfailed
Во FreeBSD существуют дополнительные флаги загрузки: bootme, bootonce, и bootfailed. Флаг bootme указывает, с какого раздела должна производиться загрузка. Флаг bootonce используется вместе с bootme, чтобы загрузиться с указанного раздела один раз и затем вернуться к обычной конфигурации. Это достигается тем, что loader(8) удаляет флаги. Последний флаг ─ bootfailed ─ указывает, что с данного раздела система не смогла загрузиться. Чтобы управлять этими флагами, воспользуйтесь утилитой gpart(8). Например:
# gpart set -a bootme -i 2 ada0
Эти флаги особенно полезны, если у вас более одного корневого раздела UFS с разными версиями FreeBSD: можно установить флаг bootme, чтобы загружаться с другого раздела.
● Примеры управления процессом загрузки с помощью команд
С помощью следующих команд можно изменить или обновить код загрузчика в MBR:
# fdisk -B
# fdisk -B -b /boot/boot0 ada0
# boot0cfg -B
# boot0cfg -s 1 -b /boot/boot0 ada0
Процесс установки zfsboot на слайс MBR:
# gpart create -s mbr ada0
# gpart add -t freebsd ada0
# gpart bootcode -b /boot/boot0 ada0
# gpart set -a active -i 1 ada0
# dd if=/dev/zero of=/dev/ada0s1 count=2
# dd if=/boot/zfsboot of=/dev/ada0s1 count=1
# dd if=/boot/zfsboot of=/dev/ada0s1 iseek=1 oseek=1024
Процесс установки загрузчика для GPT:
UFS
# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada0
ZFS
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
Создание раздела UEFI ESP вручную:
# gpart add -a 4K -t efi -s 200M ada0
# newfs_msdos /dev/ada0s1
# mount_msdosfs /dev/ada0s1 /mnt
# mkdir -p /mnt/efi/boot
# cp /boot/boot1.efi /mnt/efi/boot/bootx64.efi
● Дополнительные источники:
Вот интересные ресурсы FreeBSD, посвященные процессу загрузки, которые также могут вам пригодиться:
▪ FreeBSD Architecture Handbook - Chapter 1 - Bootstrapping and Kernel Initialization
▪ FreeBSD Handbook - Chapter 13 - FreeBSD Booting Process
▪ boot(8)
▪ boot.config(5)
▪ boot0cfg(8)
▪ boot1.efi(8)
▪ efibootmgr(8)
▪ efivar(8)
▪ fdisk(8)
▪ gptboot(8)
▪ gptzfsboot(8)
▪ zfsboot(8)
▪ zfsbootcfg(8)
▪ loader(8)
▪ loader.efi(8)
▪ nextboot(8)
▪ fastboot(8)
Tuesday, July 1, 2025
Мощь у вас на службе – управление электропитанием во FreeBSD
Оригинал: https://vermaden.wordpress.com/2018/11/28/the-power-to-serve-freebsd-power-management/
"Мощь у вас на службе" - девиз операционной системы FreeBSD, который отлично подходит к теме статьи. Десять лет назад (статья за 2022 год) - как быстро летит время - я даже сделал обои на на рабочий стол с этим лозунгом - картинка доступна по ссылке https://www.deviantart.com/vermaden/art/FreeBSD-Power-To-Serve-White-82309017
Настало время для статьи по теме управления питанием во FreeBSD - статья также относится к теме "FreeBSD на десктопе", но не только. Похоже, среди пользователей широко распространено мнение, что FreeBSD до такой степени ориентирована на серверы, что в ней отсутствуют механизмы энергосбережения. Как же они далеки от истины. На десктопах и серверах настройка потребления электроэнергии играет не слишком важную роль (хотя вы будете меньше платить за свет), но на ноутбуках корректные настройки помогут увеличить время работы от батареи и снизить шум вентилятора.
Я решил написать этот обзор, т.к. в соответствующей главе руководства пользователя FreeBSD (14.6 Power and Resource Management) не охвачены все аспекты, а статья в вики (https://wiki.freebsd.org/TuningPowerConsumption#A3._Memory) частично устарела.
FreeBSD предлагает много механизмов управления питанием:
1. Отключение устройств, не имеющих драйвера
2. Регулирование частоты и мощности ЦПУ
3. Поддержка состояний сна процессора (C1/C1E/C2/C3/…)
4. Включение/отключение режима турбо, доступного для большинства процессоров
5. Управление питанием устройств, подключенных по USB.
6. Управление питанием контроллеров и каналов передачи данных SATA/AHCI
7. Поддержка спящего режима с возможностью вхождения в него по закрытию крышки
8. Поддержка специфичных инструментов измерения потребления энергии от производителей оборудования
9. Регулирования скорости вращения вентилятора*
* Прим. переводчика: реализовано модулем acpi, который может не поддерживать ваш ноутбук, даже если система в целом поддерживает. У меня так и было: вентилятор молотил постоянно на полной мощности, из спящего режима ноут выходил через раз. Я понимаю, что спящий режим связан с прошивкой, но в линуксе (Slackware, Opensuse, PCLinuxos) такого вообще никогда не было.
10. Изменения яркости монитора
11. Индикация состояния батареи и оставшегося времени использования ноутбука от батареи
12. Управление питанием сетевых интерфейсов
13. Поддержка AMD PowerNow
14. Поддержка Intel Speed Step и Intel Speed Shift
15. Поддержка AMD Turbo core
16. Поддержка Intel Turbo boost
Пара слов о файлах, где хранятся системные настройки во FreeBSD:
● /etc/rc.conf - не требует перезагрузки системы после редактирования, только перезагрузку демонов.
● /etc/sysctl.conf - не требует перезагрузки, можно редактировать во время работы машины.
● /boot/loader.conf - требует перезагрузки после редактирования.
Содержание статьи:
▪ Просмотр текущих показаний:
Батарея
Износ батареи
Процессор
lscpu (1)
dmesg (8)
▪ Регулирование частоты процессора:
powerd
powerdxx
C-States
Режим турбо
▪ Устройства usb
▪ Управление питанием SATA/AHCI
▪ Устройства без драйвера:
Nvidia Optimus
▪ Переход в спящий режим и выход из него
▪ Сетевые карты
▪ Инструменты производителей устройств
▪ DTrace
▪ Другое:
ZFS
Приложения
▪ Оборудование
▪ Обновление 1: управление питанием графических карт
▪ Обновление 2: Температура процессоров AMD
▪ Обновление 3: Intel Speed Shift
Просмотр текущих показаний
Давайте начнём с того, как посмотреть данные о текущей частоте и состоянии процессора, режиме управления питанием устройств USB, ёмкость батареи и т.д.
◆ БАТАРЕЯ
Для просмотра статуса аккумулятора можно воспользоваться утилитой acpiconf(8). Вот её вывод для основной батареи ноутбука ThinkPad T420s, включенного в сеть:
% acpiconf -i 0
Design capacity: 44000 mWh
Last full capacity: 37930 mWh
Technology: secondary (rechargeable)
Design voltage: 11100 mV
Capacity (warn): 1896 mWh
Capacity (low): 200 mWh
Low/warn granularity: 1 mWh
Warn/full granularity: 1 mWh
Model number: 45N1037
Serial number: 28608
Type: LION
OEM info: SANYO
State: high
Remaining capacity: 100%
Remaining time: unknown
Present rate: 0 mW
Present voltage: 12495 mV
...а теперь отключим ноутбук от сети:
% acpiconf -i 0
Design capacity: 44000 mWh
Last full capacity: 37930 mWh
Technology: secondary (rechargeable)
Design voltage: 11100 mV
Capacity (warn): 1896 mWh
Capacity (low): 200 mWh
Low/warn granularity: 1 mWh
Warn/full granularity: 1 mWh
Model number: 45N1037
Serial number: 28608
Type: LION
OEM info: SANYO
State: high
Remaining capacity: 100%
Remaining time: 2:31
Present rate: 0 mW
Present voltage: 12492 mV
В поле Remaining time отображается приблизительное значение оставшегося времени работы батареи - 2 часа 31 минута.
А вот вывод acpiconf для второй батареи, которая находится в отсеке ultrabay, где был привод DVD:
% acpiconf -i 1
Design capacity: 31320 mWh
Last full capacity: 24510 mWh
Technology: secondary (rechargeable)
Design voltage: 10800 mV
Capacity (warn): 1225 mWh
Capacity (low): 200 mWh
Low/warn granularity: 1 mWh
Warn/full granularity: 1 mWh
Model number: 45N1041
Serial number: 260
Type: LiP
OEM info: SONY
State: high
Remaining capacity: 100%
Remaining time: unknown
Present rate: 0 mW
Present voltage: 12082 mV
Отсоединим ноутбук от сети:
% acpiconf -i 1
Design capacity: 31320 mWh
Last full capacity: 24510 mWh
Technology: secondary (rechargeable)
Design voltage: 10800 mV
Capacity (warn): 1225 mWh
Capacity (low): 200 mWh
Low/warn granularity: 1 mWh
Warn/full granularity: 1 mWh
Model number: 45N1041
Serial number: 260
Type: LiP
OEM info: SONY
State: discharging
Remaining capacity: 98%
Remaining time: 1:36
Present rate: 14986 mW
Present voltage: 11810 mV
При отключении от сети оставшееся время равно 1:36.
Таким образом, общее время работы от батареи составит примерно 4 часа 07 минут. То же самое значение в минутах (247) отобразится в выводе команды sysctl(8):
% sysctl hw.acpi.battery.time
hw.acpi.battery.time: 247
С помощью sysctl можно получить более подробную информацию, если вместо hw.acpi.battery.time передать ей значение hw.acpi.battery:
% sysctl hw.acpi.battery
hw.acpi.battery.info_expire: 5
hw.acpi.battery.units: 2
hw.acpi.battery.state: 1
hw.acpi.battery.time: 247
hw.acpi.battery.life: 99
При подключении к сети поле hw.acpi.battery.time будет иметь значение "-1":
% sysctl hw.acpi.battery
hw.acpi.battery.info_expire: 5
hw.acpi.battery.units: 2
hw.acpi.battery.state: 0
hw.acpi.battery.time: -1
hw.acpi.battery.life: 100
▪ Износ батареи
Со временем аккумуляторы постепенно утрачивают ёмкость. Через 1-2 года от изначальной ёмкости останется около 70%. Информация об износе содержится в полях Design capacity и Last full capacity. Я написал скрипт battery-capacity.sh, который показывает текущую ёмкость батареи в процентах от изначальной. Результат его работы выглядит так:
% battery-capacity.sh 0
Battery '0' model '45N1037' has efficiency: 86%
% battery-capacity.sh 1
Battery '1' model '45N1041' has efficiency: 78%
А вот сам скрипт:
#! /bin/sh
if [ ${#} -ne 1 ]
then
echo "usage: ${0##*/} BATTERY"
exit
fi
if acpiconf -i $1 1> /dev/null 2> /dev/null
then
DATA=$( acpiconf -i $1 )
MAX=$( echo "$data" | grep '^Design\ capacity:' | awk -F ':' '{print $2}' | tr -c -d '0-9' )
NOW=$( echo "$data" | grep '^Last\ full\ capacity:' | awk -F ':' '{print $2}' | tr -c -d '0-9' )
MOD=$( echo "$data" | grep '^Model\ number:' | awk -F ':' '{print $2}' | awk '{print $1}' )
echo -n "Battery '$1' model '$Mod' has efficiency: "
printf '%1.0f%%\n' $( bc -l -e "scale = 2; $now / $Max * 100" -e quit )
else
echo "NOPE: Battery '$1' does not exists on this system."
echo "INFO: Most systems has only '0' or '1' batteries."
exit 1
fi
◆ ПРОЦЕССОР
Информацию о состоянии процессора также можно получить с помощью команды sysctl, если передать ей значение dev.cpu.0 для первого физического ядра, dev.cpu.1 - для второго:
% sysctl dev.cpu.0
dev.cpu.0.cx_method: C1/hlt C2/io
dev.cpu.0.cx_usage_counters: 412905 0
dev.cpu.0.cx_usage: 100.00% 0.00% last 290us
dev.cpu.0.cx_lowest: C1
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
dev.cpu.0.freq: 800
dev.cpu.0.%parent: acpi0
dev.cpu.0.%pnpinfo: _HID=none _UID=0
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%driver: cpu
dev.cpu.0.%desc: ACPI CPU
Если с помощью команды kldload(8) загрузить модуль ядра coretemp(4), вы получите вдобавок показания температуры:
% sysctl dev.cpu.0
dev.cpu.0.temperature: 49.0C
dev.cpu.0.coretemp.throttle_log: 0
dev.cpu.0.coretemp.tjmax: 100.0C
dev.cpu.0.coretemp.resolution: 1
dev.cpu.0.coretemp.delta: 51
dev.cpu.0.cx_method: C1/hlt C2/io
dev.cpu.0.cx_usage_counters: 16549 0
dev.cpu.0.cx_usage: 100.00% 0.00% last 1489us
dev.cpu.0.cx_lowest: C1
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
dev.cpu.0.freq: 800
dev.cpu.0.%parent: acpi0
dev.cpu.0.%pnpinfo: _HID=none _UID=0
dev.cpu.0.%location: handle=\_PR_.CPU0
dev.cpu.0.%driver: cpu
dev.cpu.0.%desc: ACPI CPU
Остановимся подробней на самых важных показателях:
Температура ядра процессора:
dev.cpu.0.temperature: 49.0C
Состояния сна, которые поддерживает процессор:
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
Статистика пребывания процессора в состоянии сна (доступен только С1):
dev.cpu.0.cx_usage_counters: 16549 0
dev.cpu.0.cx_usage: 100.00% 0.00% last 1489us
Самое глубокое поддерживаемое состояние сна:
dev.cpu.0.cx_lowest: C1
Поддерживаемые процессором частоты и соответствующая потребляемая мощность через '/': 2500/35000 означает частоту 2,5 гигагерц и потребление мощности 35 ватт; 2501 - режим турбо. Минимальная частота 800 Mгц и потребление 9 Вт:
dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
Текущая частота процессора (будет разной при использовании демонов powerd или powerdxx)
dev.cpu.0.freq: 800
Текущая температура материнской платы:
% sysctl hw.acpi.thermal.tz0.temperature
hw.acpi.thermal.tz0.temperature: 49.1C
Чтобы посмотреть, сколько ядер в вашем процессоре, наберите одну из команд:
% grep FreeBSD/SMP /var/run/dmesg.boot
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
FreeBSD/SMP: 1 package(s) x 2 core(s)
% sysctl kern.smp.cpus
kern.smp.cpus: 2
Если описанное выше вам не нужно, можете использовать команду sysctl с флагом -d:
% sysctl -d dev.cpu.0.freq
dev.cpu.0.freq: Current CPU frequency
● lscpu
Есть сторонняя утилита под названием lscpu(8), которая выводит модель и характеристики процессора. Её нужно установить с помощью пакетного менеджера:
# pkg install lscpu
Для работы ей нужен модуль ядра cpuctl(4). Вот как выглядит её вывод у меня:
# kldload cpuctl
# lscpu
Architecture: amd64
Byte Order: Little Endian
Total CPU(s): 2
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 0
Vendor: GenuineIntel
CPU family: 6
Model: 42
Model name: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
Stepping: 7
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3M
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 cflsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline aes xsave osxsave avx syscall nx rdtscp lm lahf_lm
dmesg(8)
Также команда dmesg(8) (или файл /var/run/dmesg.boot, если прошло много времени после загрузки) выводит информацию о модели процессора и его характеристиках.
% grep CPU /var/run/dmesg.boot
CPU: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz (2491.97-MHz K8-class CPU)
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
cpu0: on acpi0
coretemp0: on cpu0
● Масштабирование частоты процессора.
Для этих целей используется демон powerd(8), включенный в установочный образ системы, или powerdxx(8) из портов или репозитория. Демон powerdxx нацелен на масштабирование частоты многоядерных процессоров: он не переводит все ядра в высокое состояние при умеренной нагрузке на систему, но некоторые предпочитают такой подход, чтобы при высокой нагрузке процессор работал на полную мощность, а при её отсутствии экономилась энергия. Т.о., нельзя сказать, что powerd лучше, чем powerdxx, или наоборот - они просто разные, что даёт вам выбор в зависимости от ваших запросов.
Оба демона настраиваются через файл /etc/rc.conf.
POWERD(8)
Вот параметры для powerd:
powerd_enable=YES
powerd_flags="-n adaptive -a hiadaptive -b adaptive -m 800 -M 1600"
Параметр "-n" обозначает режим работы демона в неопределённом состоянии системы - т.е. когда демон не может определить, работаете вы от сети или от батареи. Параметр "-a" задаёт режим для работы от сети, "-b" - от батареи. Режим adaptive менее "агрессивный" и позволяет продлить время работы от батареи. Режим hiadaptive более агрессивный, его предпочтительно использовать при работе от сети. Параметр "-m" задаёт минимальную частоту процессора, до которой демон будет понижать, а "-M" - максимальную. Частоты выражаются в мегагерцах. Подробности настройки вы можете узнать на справочной страницы man powerd(8).
POWERDXX(8)
Сначала потребуется его установить:
# pkg install powerdxx
Параметры аналогичны таковым для powerd:
powerdxx_enable=YES
powerdxx_flags="-n adaptive -a hiadaptive -b adaptive -m 800 -M 1600"
Лет десять назад настройка масштабирования частоты ЦПУ не была такой простой - можете посмотреть, как это было, в моём посте от 2008 года: HOWTO: FreeBSD CPU Scaling and Power Saving: https://forums.freebsd.org/threads/howto-freebsd-cpu-scaling-and-power-saving.172/
● C-СОСТОЯНИЯ
С-состояния настраиваются в файле /etc/rc.conf с помощью следующих параметров:
performance_cx_lowest
economy_cx_lowest
Параметр economy_cx_lowest предназначен для работы от батареи, а performance_cx_lowest - для работы от сети. Оба устанавливаются скриптом /etc/rc.d/power_profile, который запускается системой инициализации rc(8). Скрипт устанавливает значение параметра hw.acpi.cpu.cx_lowest, который задаёт и управляет всеми значениями dev.cpu.*.cx_lowest. Можете отсоединить и подсоединить сетевой кабель и посмотреть за изменениями в файле /var/log/messages:
% tail -f /var/log/messages
Nov 28 13:14:42 t420s power_profile[48231]: changed to 'economy'
Nov 28 13:14:46 t420s power_profile[56835]: changed to 'performance'
Я обычно использую такие значения:
performance_cx_lowest=C1
economy_cx_lowest=Cmax
В большинстве случаев этих настроек будет достаточно. Чтобы узнать, какие С-состояния поддерживает ваш процессор, посмотрите значение параметра dev.cpu.0.cx_supported:
% sysctl dev.cpu.0.cx_supported
dev.cpu.0.cx_supported: C1/1/1 C2/3/104
Мой процессор поддерживает только С1 и С2, но у вас их может быть больше. Я помню, что на старом ноутбуке с процессором Core2Duo была заметная задержка при переходе из активного состояния С1 в состояние сна С2. В таком случае вы можете не использовать параметры performance_cx_lowest и economy_cx_lowest, а выставить для одного ядра С1, а для остальных - С2. Таким образом ваша система будет отзывчивой даже при работе от батареи, а энергосбережение будет происходить за счёт спящих ядер.
Например, если у вас 4 ядра, и максимальное (самое глубокое) С-состояние - С3, то можете прописать такие настройки в файл /etc/rc.conf:
% grep cx_lowest /etc/sysctl.conf
dev.cpu.0.cx_lowest=C1
dev.cpu.1.cx_lowest=C3
dev.cpu.2.cx_lowest=C3
dev.cpu.3.cx_lowest=C3
● РЕЖИМ ТУРБО ДЛЯ ПРОЦЕССОРА
Включить турбо-режим можно двумя способами:
1. Если вы пользуетесь демонами powerd или powerdxx, установите максимальную частоту выше номинальной. Например, если ваш процессор поддерживает максимальную частоту 2.5 Ггц, то флаг "-M" можно установить, например, в 4000 Мгц (4 Ггц).
2. Если вы не пользуетесь службами масштабирования частоты процессора, то нужно установить параметр dev.cpu.0.freq в самое высокое значение из поддерживаемых системой, которые перечислены в dev.cpu.0.freq_levels.
Вот список поддерживаемых значений частоты моего процессора:
% sysctl dev.cpu.0.freq_levels
dev.cpu.0.freq_levels: 2501/35000 2500/35000 2200/29755 2000/26426 1800/23233 1600/20164 1400/17226 1200/14408 1000/11713 800/9140
Крайнее левое значение 2501/35000 является максимальным, значит, для включения турбо-режима надо присвоить это значение параметру dev.cpu.0.freq. При этом нужно указать только значение частоты, так как, если вы укажете ещё и мощность, то sysctl не примет параметр:
# sysctl dev.cpu.0.freq=2501/35000
sysctl: invalid integer '2501/35000'
Надо так:
# sysctl dev.cpu.0.freq=2501
dev.cpu.0.freq: 800 -> 2501
◆ УСТРОЙСТВА USB
Для просмотра списка подключенных устройств есть утилита usbconfig(8).
% usbconfig
ugen1.1: at usbus1, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=SAVE (0mA)
ugen2.1: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.1: at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen2.2: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.2: at usbus0, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
ugen0.3: at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (100mA)
ugen2.3: at usbus2, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=SAVE (0mA)
Параметр pwr (сокращение от power) указывает на текущее состояние параметра электропотребления. Возможны следующие варианты:
▪ ON
▪ OFF
▪ SAVE
Чтобы изменить состояние для устройства ugen1.1, воспользуйтесь той же утилитой usbconfig для изменения параметра power_save следующим образом:
# usbconfig -u 1 -a 1 power_save
Для управления питанием устройств USB во Freebsd нет отдельного конфигурационного файла, поэтому настройки нужно поместить в универсальный /etc/rc.local, который запускается службой rc в конце, после остальных скриптов инициализации. Вот пример конфига, где исключение сделано для устройства Lenovo USB Receiver - это моя беспроводная мышь:
% grep -A 10 POWER /etc/rc.local
# POWER SAVE USB DEVICES
usbconfig \
| grep -v 'Lenovo USB Receiver' \
| grep -v 'Unifying Receiver Logitech' \
| awk '{print $1}' \
| sed 's|ugen||'g \
| tr -d : \
| awk -F '.' '{print $1 " " $2 }' \
| while read U A
do
usbconfig -u ${U} -a ${A} power_save 2> /dev/null
done
Не включать энергосбережение для мышей и подобных устройств ввода - хорошая идея, так как иначе придётся ждать пару секунд каждый раз, когда вы захотите ими воспользоваться, что будет раздражать. Чтобы настроить энергосбережение для всех устройств USB, кроме беспроводной мыши (которая распозналась как 'Lenovo USB Receiver'), я использовал цикл for.
◆ УПРАВЛЕНИЕ ПИТАНИЕМ КОНТРОЛЛЕРОВ SATA/AHCI
Во FreeBSD есть драйвер для управления каналами AHCI - это acpich(4). Настройки управления электропитанием устанавливаются во время загрузки через параметр hint.ahcich.*.pm_level файла /boot/loader.conf. У меня настраивается до 8 каналов, хотя в системе присутствуют только три.
% grep ahcich /var/run/dmesg.boot
ahcich0: at channel 0 on ahci0
ahcich1: at channel 1 on ahci0
ahcich4: at channel 4 on ahci0
ada0 at ahcich0 bus 0 scbus0 target 0 lun 0
Настройки для несуществующих устройств не создают проблем и не приводят к появлению сообщений об ошибках, зато можно пользоваться одним конфигурационным файлом на разных системах. Вот описание параметра hint.ahcich.*.pm_level со справочной страницы man ahci(4):
" hint.ahcich.X.pm_level
Управляет питанием интерфейса SATA на указанном канале, позволяет сэкономить некоторое количество энергии за счёт увеличения задержки выполнения команд.
Некоторые контроллеры, такие как ICH8, не поддерживают режимы 2 и 3 при использовании NCQ. Из-за искусственно созданной задержки ввода данных снижение производительности в режимах 4 и 5 гораздо меньше, чем в режимах 2 и 3."
Поддерживаемые драйвером варианты управления питанием:
0 - управление питанием интерфейса отключено (по умолчанию)
1 - изменение статуса управления питанием инициируется устройством, а не хостом
2 - хост инициирует переход в состояние PARTIAL каждый раз, когда порт переходит в состояние ожидания
3 - хост инициирует переход в состояние SLUMBER каждый раз, когда порт переходит в состояние ожидания
4 - драйвер инициирует переход в состояние PARTIAL спустя 1 секунду после перехода порта в состояние ожидания
5 - драйвер инициирует переход в состояние SLUMBER спустя 125 миллисекунд после перехода порта в состояние ожидания
Вот мои настройки из файла /boot/loader.conf:
# AHCI POWER MANAGEMENT FOR EVERY USED CHANNEL (ahcich 0-7)
hint.ahcich.0.pm_level=5
hint.ahcich.1.pm_level=5
hint.ahcich.2.pm_level=5
hint.ahcich.3.pm_level=5
hint.ahcich.4.pm_level=5
hint.ahcich.5.pm_level=5
hint.ahcich.6.pm_level=5
hint.ahcich.7.pm_level=5
◆ УСТРОЙСТВА БЕЗ ДРАЙВЕРА
Во FreeBSD есть возможность не подавать питание на устройства, для которых в системе нет драйвера. За это отвечает параметр hw.pci.do_power_nodriver, который устанавливается в файле /boot/loader.conf. Вот его описание со страницы руководства man pci(4):
"hw.pci.do_power_nodriver (Defaults to 0)
Переводит устройство в состояние сниженного энергопотребления (D3), если для него нет подходящего драйвера.
Этот параметр может принимать одно из следующих значений:
0 - все устройства включены и потребляют максимум энергии (по умолчанию)
1 - как 2, но контроллеры памяти также не отключаются
2 - большинство устройств отключены, кроме дисплея, памяти и периферии
3 - отключает все устройства PCI, для которых нет драйвера"
Вот мои настройки из файла /boot/loader.conf:
# POWER OFF DEVICES WITHOUT ATTACHED DRIVER
hw.pci.do_power_nodriver=3
Команда pciconf(8) показывает, какие устройства есть в системе и какими драйверами они управляются. Если драйвера в системе нет, вы увидите "none*@" вместо названия устройства - в примере ниже это "none0@". Для большинства драйверов есть страницы справочного руководства - например, для драйвера устройства em0 страница man em(4), а для устройства xhci0 - страница man xhci(4).
% pciconf -l
hostb0@pci0:0:0:0: class=0x060000 card=0x21d217aa chip=0x01048086 rev=0x09 hdr=0x00
vgapci0@pci0:0:2:0: class=0x030000 card=0x21d217aa chip=0x01268086 rev=0x09 hdr=0x00
none0@pci0:0:22:0: class=0x078000 card=0x21d217aa chip=0x1c3a8086 rev=0x04 hdr=0x00
em0@pci0:0:25:0: class=0x020000 card=0x21ce17aa chip=0x15028086 rev=0x04 hdr=0x00
ehci0@pci0:0:26:0: class=0x0c0320 card=0x21d217aa chip=0x1c2d8086 rev=0x04 hdr=0x00
hdac0@pci0:0:27:0: class=0x040300 card=0x21d217aa chip=0x1c208086 rev=0x04 hdr=0x00
pcib1@pci0:0:28:0: class=0x060400 card=0x21d217aa chip=0x1c108086 rev=0xb4 hdr=0x01
pcib2@pci0:0:28:1: class=0x060400 card=0x21d217aa chip=0x1c128086 rev=0xb4 hdr=0x01
pcib3@pci0:0:28:3: class=0x060400 card=0x21d217aa chip=0x1c168086 rev=0xb4 hdr=0x01
pcib4@pci0:0:28:4: class=0x060400 card=0x21d217aa chip=0x1c188086 rev=0xb4 hdr=0x01
ehci1@pci0:0:29:0: class=0x0c0320 card=0x21d217aa chip=0x1c268086 rev=0x04 hdr=0x00
isab0@pci0:0:31:0: class=0x060100 card=0x21d217aa chip=0x1c4f8086 rev=0x04 hdr=0x00
ahci0@pci0:0:31:2: class=0x010601 card=0x21d217aa chip=0x1c038086 rev=0x04 hdr=0x00
ichsmb0@pci0:0:31:3: class=0x0c0500 card=0x21d217aa chip=0x1c228086 rev=0x04 hdr=0x00
iwn0@pci0:3:0:0: class=0x028000 card=0x11118086 chip=0x42388086 rev=0x3e hdr=0x00
sdhci_pci0@pci0:5:0:0: class=0x088000 card=0x21d217aa chip=0xe8221180 rev=0x07 hdr=0x00
xhci0@pci0:13:0:0: class=0x0c0330 card=0x01941033 chip=0x01941033 rev=0x04 hdr=0x00
Для более подробного вывода используйте флаг -v:
% pciconf -l -v
(...)
xhci0@pci0:13:0:0: class=0x0c0330 card=0x01941033 chip=0x01941033 rev=0x04 hdr=0x00
vendor = 'NEC Corporation'
device = 'uPD720200 USB 3.0 Host Controller'
class = serial bus
subclass = USB
◆ Nvidia OPTIMUS
Если по каким-то причинам вы не можете отключить дискретную видеокарту Nvidia в BIOS/UEFI, то можете сделать это с помощью скрипта, и карта не будет потреблять энергию. Для работы скрипта нужен модуль acpi_call(4), который входит в пакет acpi_call.
# mkdir /root/bin
# cd /root/bin
# fetch https://people.freebsd.org/~xmj/turn_off_gpu.sh
# pkg install acpi_call
# kldload acpi_call
# chmod +x /root/bin/turn_off_gpu.sh
# /root/bin/turn_off_gpu.sh
Вы можете прописать скрипт в файл /etc/rc.local после параметров энергосбережения устройств USB таким образом:
# DISABLE NVIDIA CARD
/root/bin/turn_off_gpu.sh
При этом работающий вызов ACPI будет храниться в файле /root/.gpu_method и выполняться каждый раз при загрузке.
◆ СПЯЩИЙ РЕЖИМ И ВЫХОД ИЗ НЕГО
Злейшие враги корректного входа и выхода из спящего режима - это баги в прошивке вашего ноутбука (BIOS или UEFI). Иногда помогает отключения Bluetooth - например, это работает на ThinkPad T420s. Чтобы посмотреть, какие режимы сна доступны в вашей системе, проверьте значение параметра hw.acpi.supported_sleep_state подсистемы sysctl(8):
% sysctl hw.acpi.supported_sleep_state
hw.acpi.supported_sleep_state: S3 S4 S5
Чтобы перевести систему в состояние сна ACPI S3 (suspend - ждущий режим), можно воспользоваться утилитами acpiconf(8) или zzz(8):
# zzz
или
# acpiconf -s 3
На странице руководства для zzz(8) сказано, что это одно и то же.
Также можно задать параметр sysctl(8), чтобы ноутбук переходил в режим ожидания каждый раз, когда вы закрываете крышку. Для этого в файле /etc/sysctl.conf нужно выставить значение hw.acpi.lid_switch_state=S3. Независимо от способа перехода в спящий режим - закрытие крышки или команда, - после открытия крышки ноутбук выйдет из него. Если вы дали команду zzz и не закрыли крышку, то для выхода из сна её надо либо закрыть и открыть, либо нажать копку питания. Разумеется, эти команды работают не только на ноутбуках - вы можете пользоваться ими на десктопе или даже на сервере.
Для подсистем ACPI от разных производителей существуют свои модули ядра. Вот они:
/boot/kernel/acpi_asus_wmi.ko
/boot/kernel/acpi_asus.ko
/boot/kernel/acpi_dock.ko
/boot/kernel/acpi_fujitsu.ko
/boot/kernel/acpi_hp.ko
/boot/kernel/acpi_ibm.ko
/boot/kernel/acpi_panasonic.ko
/boot/kernel/acpi_sony.ko
/boot/kernel/acpi_toshiba.ko
/boot/kernel/acpi_video.ko
/boot/kernel/acpi_wmi.ko
Например, если у вас IBM/Lenovo ThinkPad, воспользуйтесь модулем acpi_ibm.ko:
# kldload acpi_ibm
После загрузки соответствующего модуля у вас появятся новые параметры sysctl, которые можно будет настроить - например скорость вращения вентилятора, подсветка клавиатуры или яркость монитора. Ниже приведен раздел dev.acpi_ibm, появившийся в sysctl после загрузки модуля ядра acpi_ibm(4):
% sysctl dev.acpi_ibm
dev.acpi_ibm.0.handlerevents: NONE
dev.acpi_ibm.0.mic_led: 0
dev.acpi_ibm.0.fan: 0
dev.acpi_ibm.0.fan_level: 0
dev.acpi_ibm.0.fan_speed: 0
dev.acpi_ibm.0.wlan: 1
dev.acpi_ibm.0.bluetooth: 0
dev.acpi_ibm.0.thinklight: 0
dev.acpi_ibm.0.mute: 0
dev.acpi_ibm.0.volume: 0
dev.acpi_ibm.0.lcd_brightness: 0
dev.acpi_ibm.0.hotkey: 1425
dev.acpi_ibm.0.eventmask: 134217727
dev.acpi_ibm.0.events: 1
dev.acpi_ibm.0.availmask: 134217727
dev.acpi_ibm.0.initialmask: 2060
dev.acpi_ibm.0.%parent: acpi0
dev.acpi_ibm.0.%pnpinfo: _HID=LEN0068 _UID=0
dev.acpi_ibm.0.%location: handle=\_SB_.PCI0.LPC_.EC__.HKEY
dev.acpi_ibm.0.%driver: acpi_ibm
dev.acpi_ibm.0.%desc: IBM ThinkPad ACPI Extras
dev.acpi_ibm.%parent:
Вот описание наиболее важных параметров:
dev.acpi_ibm.0.mic_led - включение светодиодного индикатора на кнопке выключения микрофона
dev.acpi_ibm.0.fan - выбрать, хотите ли вы сами управлять скоростью вращения вентилятора (0) или оставить настройки по умолчанию от производителя (1)
dev.acpi_ibm.0.fan_level - если вентилятор работает, установить скорость вращения
dev.acpi_ibm.0.fan_speed - показывает текущую скорость вращения (в RPM - оборотах в минуту)
dev.acpi_ibm.0.wlan - включить/выключить WiFi (если он включен в BIOS)
dev.acpi_ibm.0.bluetooth - включить/выключить Bluetooth (если он включен в BIOS)
dev.acpi_ibm.0.thinklight - включить/выключить Thinklight
dev.acpi_ibm.0.mute - включить/выключить звук в динамиках
dev.acpi_ibm.0.volume - уровень громкости динамиков
dev.acpi_ibm.0.lcd_brightness - яркость экрана
В большинстве случаев настройка этих параметров не требуется, так как можно использовать определённые производителем сочетания клавиш (обычно включающие клавишу Fn) или соответствующие кнопки. Но иногда нужны индивидуальные настройки, свои сочетания клавиш или контроль скорости вращения вентилятора в зависимости от температуры процессора - в таких случаях параметры вам и пригодятся.
Например, мне недавно показалось, что вентилятор работает слишком шумно, и я написал скрипт для cron(8) на базе скрипта acpi-thinkpad-fan.sh, чтобы при понижении температуры процессора вентилятор снижал обороты. Этот скрипт я выкладываю здесь - возможно, он будет полезен вам. Вкратце он делает следующее: отключает вентилятор, если температура процессора ниже 50°C; если температура в диапазоне 50-60 градусов, значение скорости устанавливается в '1'; при превышении 60°C значение скорости устанавливается в '3'.
#! /bin/sh
if ! kldstat | grep -q acpi_ibm.ko
then
doas kldload acpi_ibm
fi
doas sysctl dev.acpi_ibm.0.fan=0 1> /dev/null
TEMP=$( sysctl -n hw.acpi.thermal.tz0.temperature | awk -F'.' '{print $1}' )
if [ ${TEMP} -lt 50 ]
then
doas sysctl dev.acpi_ibm.0.fan_level=0 1> /dev/null
exit 0
fi
if [ ${TEMP} -lt 60 ]
then
doas sysctl dev.acpi_ibm.0.fan_level=1 1> /dev/null
exit 0
fi
if [ ${TEMP} -ge 60 ]
then
doas sysctl dev.acpi_ibm.0.fan_level=3 1> /dev/null
exit 0
fi
А вот пункт в таблице crontab(5):
% crontab -l
# ACPI/IBM/FAN
* * * * * ~/scripts/acpi-thinkpad-fan.s
◆ СЕТЕВЫЕ ИНТЕРФЕЙСЫ
Если драйвер поддерживает энергосбережение для сетевой карты, его можно включить командой ifconfig(8), передав ей параметр powersave:
# ifconfig wlan0 powersave
Я использую его в своём скрипте для управления настройками сети network.sh, который подробно описан в статье по ссылке: https://vermaden.wordpress.com/2018/03/24/freebsd-network-management-with-network-sh-script/
◆ УТИЛИТЫ ПРОИЗВОДИТЕЛЕЙ
Во FreeBSD доступны также утилиты производителей, такие как powermon(8). Для её работы требуется модуль ядра cpuctl(4).
# pkg install powermon
# kldload cpuctl
# powermon
Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz
(Arch: Sandy Bridge, Limit: 44W)
5.11W [=======> ]
Package: Uncore: x86 Cores: GPU:
Current: 5.11W Current: 3.17W Current: 1.73W Current: 0.21W
Total: 98.33J Total: 60.86J Total: 33.49J Total: 3.98J
◆ D-TRACE
Фреймворк динамической трассировки, который, как и ZFS, пришёл во FreeBSD из Solaris/Illumos, также может оказаться полезен в борьбе за увеличение времени работы от батареи.
Для начала его надо установить:
# pkg install dtrace-toolkit
Ваша система выходит из режима энергосбережения или активизирует процессор, когда требуется выполнить какую-то задачу. Чтобы посмотреть список выполняемых процессов, обычно используются ps(1) или top(1), но они не показывают, что именно запускается в данный момент или как часто выполняется какой-либо процесс. В этом вам поможет DTrace.
Воспользуемся скриптом /usr/share/dtrace/toolkit/execsnoop из пакета dtrace-toolkit. Он выводит ВСЕ ВЫПОЛНЯЕМЫЕ КОМАНДЫ со всеми аргументами. Если в данный момент ничего не выполняется, вывод будет пустым.
Вот пример вывода при обновлении показаний моей панели dzen2:
# /usr/local/share/dtrace-toolkit/execsnoop
UID PID PPID ARGS
1000 97748 97509 /usr/local/bin/zsh -c ~/scripts/dzen2-update.sh > ~/.dzen2-fifo
1000 97748 1 /bin/sh /home/vermaden/scripts/dzen2-update.sh
1000 99157 97748 sysctl -n kern.smp.cpus
1000 311 97748 ps ax -o %cpu,rss,command -c
1000 3118 1521 awk -v SMP=200 /\ idle$/ {printf("%.1f%%",SMP-$1)}
1000 4462 97748 date +%Y/%m/%d/%a/%H:%M
1000 4801 97748 sysctl -n dev.cpu.0.freq
1000 6009 97748 sysctl -n hw.acpi.thermal.tz0.temperature
1000 6728 97748 sysctl -n vm.stats.vm.v_inactive_count
1000 7043 97748 sysctl -n vm.stats.vm.v_free_count
1000 7482 97748 sysctl -n vm.stats.vm.v_cache_count
1000 10363 8568 bc -l
1000 10863 10363 dc -x
1000 13143 7773 grep --color -q ^\.
1000 13798 97748 /bin/sh /home/vermaden/scripts/__conky_if_ip.sh
1000 15089 14235 ifconfig -u
1000 16439 14235 grep -v 127.0.0.1
1000 17738 14235 grep -c inet
1000 19069 18612 ifconfig -l -u
1000 19927 18612 sed s/lo0//g
1000 20772 13798 ifconfig wlan0
1000 23388 21410 grep ssid
1000 24588 13798 grep -q "
1000 25965 25282 awk /ssid/ {print $2}
1000 27917 27217 awk /inet / {print $2}
1000 29941 97748 /bin/sh /home/vermaden/scripts/__conky_if_gw.sh
1000 32808 31412 route -n -4 -v get default
1000 34012 31412 awk END{print $2}
1000 34895 97748 /bin/sh /home/vermaden/scripts/__conky_if_dns.sh
1000 36118 34895 awk /^nameserver/ {print $2; exit} /etc/resolv.conf
1000 37628 97748 /bin/sh /home/vermaden/scripts/__conky_if_ping.sh dzen2
1000 38829 37628 ping -c 1 -s 0 -t 1 -q 9.9.9.9
1000 42079 41566 mixer -s vol
1000 42177 41566 awk -F : {printf("%s",$2)}
1000 44434 43254 zfs list -H -d 0 -o name,avail
1000 45866 43254 awk {printf("%s/%s ",$1,$2)}
1000 47004 97748 /bin/sh /home/vermaden/scripts/__conky_battery_separate.sh dzen2
1000 48282 47004 sysctl -n hw.acpi.battery.units
1000 49494 47004 sysctl -n hw.acpi.battery.life
1000 49948 47004 sysctl -n hw.acpi.acline
1000 52073 51441 acpiconf -i 0
1000 53055 51441 awk /^State:/ {print $2}
1000 53981 53186 acpiconf -i 0
1000 55354 53186 awk /^Remaining capacity:/ {print $3}
1000 55968 55631 acpiconf -i 1
1000 57187 55631 awk /^State:/ {print $2}
1000 58405 57471 acpiconf -i 1
1000 59201 57471 awk /^Remaining capacity:/ {print $3}
1000 60961 59252 bsdgrep -v -E (COMMAND|idle)$
1000 63534 59252 head -3
1000 62194 59252 sort -r -n
1000 64629 59252 awk {printf("%s/%d%%/%.1fGB ",$3,$1,$2/1024/1024)}
1000 64634 93198 tail -1 /home/vermaden/.dzen2-fifo
Сколько процессов выполняется, чтобы просто обновить значения на панели! Вот поэтому я обновляю информацию на dzen2 раз в пять минут, а если мне нужны точные показания и статус системы на данный момент, то щёлкаю мышью по панели, и она запускает все эти команды.
Используя DTrace таким образом, вы узнаете о ненужных процессах, сокращающих время работы от батареи. Конфигурацию dzen2 вы можете найти в моей статье о freebsd на десктопе по ссылке: https://vermaden.wordpress.com/2018/07/05/freebsd-desktop-part-13-configuration-dzen2/
◆ ZFS
По умолчанию ZFS пишет группу транзакций каждые 5 секунд, и это подходящее значение для параметра vfs.zfs.txg.timeout. При необходимости значение можно немного увеличить - например, до 10 секунд. Я упомянул этот параметр, потому что во многих руководствах из соображений производительности рекомендуется устанавливать его в 1, но имейте в виду, что значение 1 не даст вашему диску (и процессору) переходить в спящий режим, что сократит время работы от батареи.
Если хотите поэкспериментировать со значением параметра vfs.zfs.txg.timeout, его значение задаётся в файле /boot/loader.conf.
◆ ПРИЛОЖЕНИЯ
Время работы от батареи сильно зависит также от используемых приложений. Например, Thunar потребляет меньше процессорного времени, чем Caja или Nautilus. Текстовый редактор Geany потребляет меньше ресурсов ЦПУ и памяти, чем Scite, Gedit или даже GVim. Не говоря уже о том, что настроенный под себя Openbox/Fluxbox/${ваш_любимый_оконный_менеджер} будет потреблять намного меньше процессорного времени, чем среда рабочего стола типа GNOME или MATE.
◆ ОБОРУДОВАНИЕ
Иногда есть возможность в буквальном смысле купить больше времени работы от батареи. Например, если вы собрались покупать новый SSD для ноутбука, выбирайте не самый быстрый, а самый энергоэффективный - разницу в производительности вы, вероятно, всё равно не заметите, но оцените то, что батарея будет медленней разряжаться.
Большинство модулей оперативной памяти имеют напряжение питания 1,5 В, но есть вероятность, что ваш ноутбук поддерживает маломощные модули DDR с напряжением питания 1,35 В, что увеличит время работы от батареи. Также имейте в виду, что каждая планка потребляет примерно 0,5-1 Ватт, поэтому, если использовать один модуль на 8 Гб, она будет потреблять меньше, чем две по 4 Гб. Хотя это снизит производительность, потому что с одним модулем памяти не получится использовать двухканальный режим, и память будет работать медленней. В некоторых ноутбуках (ThinkPad W520, например) четыре слота для памяти, и можно использовать две планки по 8 Гб вместо четырёх по 4 Гб, что позволить дольше работать от батареи без потери производительности.
Иногда есть возможность вместо DVD-привода поставить дополнительную батарею - например, в ноутбуках Dell Latitude D630, ThinkPad T420s или ThinkPad T500/W500. У некоторых ноутбуков есть тонкие дополнительные аккумуляторы (slice battery), которые крепятся к нижней крышке - это ThinkPad X220 или T420/T520/W520, а из первого поколения - ThinkPad X1.
Надеюсь, эта информация поможет вам сэкономить время работы от батареи или хотя бы немного электроэнергии.
◆ ВИДЕОКАРТЫ И ЭНЕРГОСБЕРЕЖЕНИЕ
Если у вас установлен пакет graphics/drm-kmod, то, скорее всего, у вас драйвер i915kms.ko последней версии.
Чтобы настроить интегрированную видеокарту Intel на максимальное энергосбережение, вставьте в файл /boot/loader.conf следующие строки:
# INTEL DRM WITH graphics/drm-kmod PACKAGE (NEW)
# SKIP UNNECESSARY MODE SETS AT BOOT TIME
compat.linuxkpi.fastboot=1
# USE SEMAPHORES FOR INTER RING SYNC
compat.linuxkpi.semaphores=1
# ENABLE POWER SAVING RENDER C-STATE 6
compat.linuxkpi.enable_rc6=7
# ENABLE POWER SAVING DISPLAY C-STATES
compat.linuxkpi.enable_dc=2
# ENABLE FRAME BUFFER COMPRESSION FOR POWER SAVINGS
compat.linuxkpi.enable_fbc=1
Раньше были такие настройки, но теперь их нет:
# INTEL DRM WITH graphics/drm-kmod PACKAGE (OLD)
drm.i915.enable_rc6=7
drm.i915.semaphores=1
drm.i915.intel_iommu_enabled=1
◆ ТЕМПЕРАТУРА ПРОЦЕССОРОВ AMD
Для процессоров Intel есть модуль coretemp (4), а для AMD - amdtemp (4), который предоставляет дополнительную информацию о температуре.
◆ INTEL SPEED SHIFT
Поскольку я пользуюсь FreeBSD на очень приличном, но древнем ноутбуке ThinkPad W520 2011 года, эта опция для меня загадка, но она может быть полезна тем, у кого машины поновей.
FreeBSD поддерживает технологию intel speed shift для процессоров 6-го поколения, начиная с микроархитектуры skylake - подробнее можете почитать на странице руководства hwpstate_intel(4). Чтобы воспользоваться технологией, добавьте в файл /boot/loader.conf следующую строку:
machdep.hwpstate_pkg_ctrl=0
Затем в файл /etc/sysctl.conf нужно добавить для каждого потока (не ядра) строки с нужным вам значением параметра:
dev.hwpstate_intel.N.epp=Y
Здесь N - номер потока. Для двухъядерного процессора с четырьмя потоками получится четыре строки. Если в процессоре 8 ядер и 8 потоков, то должно быть 8 строк.
Параметр "Y" может принимать следующие значения:
▪ 0 - максимальная производительность;
▪ 50 - среднее между макс. производительностью и макс. энергосбережением;
▪ 100 - максимальное энергосбережение.
Чтобы получить максимальное энергосбержение, надо выстаивить 100 для всех потоков:
dev.hwpstate_intel.0.epp=100
dev.hwpstate_intel.1.epp=100
dev.hwpstate_intel.2.epp=100
dev.hwpstate_intel.3.epp=100
dev.hwpstate_intel.4.epp=100
dev.hwpstate_intel.5.epp=100
dev.hwpstate_intel.6.epp=100
dev.hwpstate_intel.7.epp=100
Можно выставлять разные значения для разных потоков:
dev.hwpstate_intel.0.epp=0
dev.hwpstate_intel.1.epp=50
dev.hwpstate_intel.2.epp=100
dev.hwpstate_intel.3.epp=100
dev.hwpstate_intel.4.epp=100
dev.hwpstate_intel.5.epp=100
dev.hwpstate_intel.6.epp=100
dev.hwpstate_intel.7.epp=100
В идеале используйте макс. энергосбережение при работе от батареи и макс. производительность при работе от сети. Для этого вам понадобится скрипт, выложенный ниже, и демон cron(8).
Скрипт:
#! /bin/sh
case $( sysctl -n hw.acpi.acline ) in
(0) # BATTERY
doas sysctl dev.hwpstate_intel.0.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.1.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.2.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.3.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.4.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.5.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.6.epp=100 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.7.epp=100 1> /dev/null 2> /dev/null
;;
(1) # AC
doas sysctl dev.hwpstate_intel.0.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.1.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.2.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.3.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.4.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.5.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.6.epp=0 1> /dev/null 2> /dev/null
doas sysctl dev.hwpstate_intel.7.epp=0 1> /dev/null 2> /dev/null
;;
esac
Строка для crontab:
% crontab -l
# INTEL/SPEED/SHIFT
* * * * * ~/scripts/acpi-intel-speed-shift.sh
Подразумевается, что у вас есть необходимые права доступа для doas(1). Если вы используете sudo(8), а не doas, внесите изменения в скрипт.
К сожалению, у меня нет ноутбука, процессор которого поддерживал бы Intel Speed Shift, поэтому я не знаю, являются ли значения 0 и 50 для первых двух потоков оптимальными. Возможно, лучше выставить 100 для всех потоков для большей экономии энергии. Когда куплю такой ноутбук, я дам знать.
Saturday, May 24, 2025
Оценка потребления памяти в Линукс (RSS и VSZ)
Оригинал: https://web.archive.org/web/20120520221529/http://emilics.com/blog/article/mconsumption.html
Примечание переводчика: статья написана в 2012 году, когда RSS считался так, как пишет автор. В настоящий момент в выводе программ вроде ps используется PSS, которая обозначается как RSS. Если вы запустите скрипт на питоне, ссылка на который есть в статье, то получите значение, которое совпадает с RSS в современной системе.
В статье рассказывается об объективном методе оценки потребления памяти процессом в Линукс. В Линукс имеется менеджер виртуальной памяти, поэтому определить, сколько памяти потребляет один процесс, не так просто, как многие думают. В статье объясняется, что означает каждый индикатор потребления памяти.
Вывод для тех, кому некогда читать
Я считаю объективной метрику PSS(Proportional Set Size) для оценки потребления памяти, если ваша линукс-система её поддерживает. Функция на Питоне, приведённая ниже, возвращает PSS для процесса с заданным ID в кибибайтах (1 Kib=1024 байт). Если она не работает, то, вероятно, ваша операционная система не отображает PSS.
import sys, re
def pss_of_process(pid):
with file('/proc/%s/smaps' % pid) as fp:
return sum([int(x) for x in re.findall('^Pss:\s+(\d+)', fp.read(), re.M)])
Вот ссылка на скрипт pss.py, который выводит список процессов и значение PSS для них: https://web.archive.org/web/20130227090134/http://emilics.com/media/pub/pss.py
Чтобы увидеть значения PSS для всех запущенных в пространстве пользователя процессов, выполните команду:
% sudo python pss.py
Вывод команды (на машине переводчика):
admin 1116 934 /bin/sh /usr/bin/startx
admin 1160 909 sh /home/admin/wmaker.sh
messagebus 950 737 /usr/bin/dbus-daemon --system
admin 1146 549 /usr/bin/dbus-daemon --syslog --fork --print-pid 5 --print-address 7 --session
admin 3233 481 /usr/bin/dbus-daemon --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork --print-
admin 1155 459 wmsystemtray
admin 1145 446 dbus-launch --exit-with-session /usr/bin/wmaker
root 1089 371 dhcpcd: [privileged proxy] wlan0 [ip4]
dhcpcd 3138 333 dhcpcd: wlan0 [ip4]
root 1063 318 /sbin/agetty 38400 tty3 linux
Программа распространяется под лицензией BSD.
Аллегория, чтобы понять идею
В статье объясняется значение трёх индикаторов, которые можно использовать для определения размера потребляемой одним процессом памяти в Линукс. Это VSZ (Virtual Memory Size) - размер виртуальной памяти, RSS (Resident Set Size) - размер резидентной памяти, и PSS (Proportional Set Size) - пропорциональный размер резидентной памяти.
Хоть аналогия будет неточной, давайте рассмотрим следующий пример, чтобы понять смысл индикаторов: три человека живут в одной комнате. Будем считать, что каждый человек - это процесс, а стоимость проживания - потребление памяти. В этой аналогии потребление памяти одним процессом будет соответствовать расходам на оплату комнаты для одного человека.
У каждого жильца свой сотовый телефон, и расходы на сотовую связь они оплачивают отдельно. Все три индикатора - VSZ, RSS, PSS, - будут учитывать расходы на сотовую связь для каждого индивидуально, здесь проблем нет.
Вместе с комнатой сдаётся гараж, который можно использовать, если за него заплатить. Но у всех троих нет машины, и они им не пользуются. Тем не менее, VSZ будет добавлять всю стоимость гаража каждому в расходы, даже если человек им не пользуется. То есть VSZ - это расходы на проживание, включая все доступные опции, независимо от их фактического потребления. RSS и PSS учитывают только фактические расходы и, соответственно, не будут учитывать стоимость неиспользуемого гаража.
Все трое пользуются одним шлюзом для интернета и кабельным телевидением, поэтому делят затраты между собой. В этом случае RSS будет добавлять полную стоимость интернета и TV каждому жильцу, даже если стоимость поделена между ними. RSS устроен так, чтобы подсчитывать расходы, будто они ни с кем не разделены.
PSS будет добавлять в оплату проживания каждому треть стоимости интернета и телевидения, поскольку счёт делится между всеми жильцами. Эта метрика более объективна, чем RSS, так как учитывает то, что расходы поделены.
Давайте немного усложним аналогию, чтобы понять ограничения для PSS. Один из жильцов много сидит в интернете, а телевизор смотрит мало, поэтому они договорились, что он оплачивает 50% стоимости интернета и 20% телевидения. PSS не учитывает подобные ситуации и просто делит затраты на интернет и телевидение поровну - каждому третью часть.
Я считаю, что PSS - наиболее объективная метрика, хотя у неё есть свои ограничения, и в некоторых ситуация RSS предпочтительней - в случае, если вы хотите узнать, сколько будете платить, если съедете с комнаты и будете жить одни.
Управление виртуальной памятью
В старые добрые времена узнать количество потребляемой одним процессом памяти для операционных систем типа MS-DOS или µITRON было просто. Однако в современных системах всё сложнее, поскольку они снабжены менеджером виртуальной памяти, который даёт множество преимуществ, но при этом усложняет расчет используемой памяти для одного процесса.
Менеджер виртуальной памяти в Линукс имеет ряд важных функций, связанных с измерением потребления памяти. Прежде чем перейти к их объяснению, давайте посмотрим результат команды ps aux, которая выдаёт информацию о процессах (Прим. переводчика: это вывод с моей машины).
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2480 1752 ? Ss 12:26 0:00 init [3]
root 2 0.0 0.0 0 0 ? S 12:26 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< 12:26 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< 12:26 0:00 [rcu_par_gp]
root 5 0.0 0.0 0 0 ? I< 12:26 0:00 [slub_flushwq]
root 6 0.0 0.0 0 0 ? I< 12:26 0:00 [netns]
root 8 0.0 0.0 0 0 ? I< 12:26 0:00 [kworker/0:0H-events_highpri]
root 10 0.0 0.0 0 0 ? I< 12:26 0:00 [mm_percpu_wq]
В странице руководства man ps написано следующее:
RSS - объём резидентной памяти - памяти, которую использует процесс, не считая выгруженной в своп. Алиас rsz.
VSZ - объём виртуальной памяти процесса в кибибайтах. Device mapper на данный момент не учитывается, алиас vsz.
Какую метрику использовать: RSS или VSZ? Далее будет объяснено, как работают оба эти индикатора, а также PSS (Proportional Set Size). Команда ps не отображает PSS, но его можно найти в файловой системе /proc.*
*Примечание переводчика: конкретно в /proc/$pid/status, где оно называется теперь RSS.
Технические термины:
Страница - блок памяти, которым оперирует менеджер памяти в Линукс. Как правило, её размер составляет 4096 байт.
Физическая память - реальная память - как правило, RAM, - которая имеется в компьютере.
Виртуальная память - память, выделяемая под процесс. Процесс считает, что у него своя собственная непрерывная память, изолированная от других процессов, независимо от объёма физической памяти компьютера и от того, сколько ещё процессов на неё претендуют. Страницы виртуальной памяти отображаются в физические страницы и, таким образом, процессы оперируют только виртуальной памятью.
VSZ и Demand Paging
Использовать метрику vsz для измерения памяти, потребляемой процессом, не имеет особого смысла из-за функции Demand Paging - загрузка страниц в память при обращении к ним, - которая предотвращает ненужное потребление памяти.
Например, функционал текстового редактора emacs позволяет работать с XML-файлами. Однако, большую часть времени эта функция не используется, поэтому нет смысла загружать её в физическую память, если пользователю надо отредактировать обычный текст. Demand Paging не даёт загружать страницы, к которым процесс не обращается. Функция работает следующим образом: при запуске программы Линукс выделяет процессу виртуальную память, но не загружает в физическую память страницы, к которым она не обращается в данный момент. Когда программа вызывает функцию из виртуальной памяти, модуль управления памятью процессора - MMU - сообщает ОС, что страница не загружена. Тогда Линукс приостанавливает выполнение процесса, загружает страницу в физическую память, после чего снова запускает процесс. При этом процессу не нужно знать, что он был приостановлен - он просто полагает, что функция загружена в память, и использует её.
VSZ (virtual memory size) показывает размер всей виртуальной памяти процесса, независимо от того, загружены страницы в физическую память или нет. Таким образом, это не объективный показатель потребления памяти, включающий в себя фактически не используемые страницы.
RSS (Resident Set Size) и разделяемые библиотеки
RSS показывает общее количество страниц процесса, загруженных в физическую память. Может показаться, что это и есть настоящий объём потребляемой процессом памяти, и что эта метрика лучше, чем VSZ, но всё не так просто из-за разделяемых (динамических) библиотек.
Библиотека - это модуль, который программы используют для реализации определённого функционала. Например, libpng.so занимается сжатием и распаковкой изображений в формате PNG, а libxml2.so - обработкой файлов XML. Чтобы программистам каждый раз не писать эти функции, можно пользоваться библиотеками, которые уже написаны.
Разделяемый объект - это библиотека, которой одновременно пользуются несколько программ или процессов. Пусть у нас запущено одновременно два процесса, которым требуется функционал библиотеки libxml2.so. Чтобы не загружать несколько раз одинаковые страницы памяти, Линукс загружает один экземпляр библиотеки в физическую память и отображает его в виртуальную память обоих процессов. Процессам неважно, используют ли они функцию совместно, так как они получают доступ к ней в своей виртуальной памяти. Разделяемые библиотеки позволяют не дублировать страницы в памяти.
А теперь вернёмся к примеру про emacs, который может работать с файлами в формате XML благодаря библиотеке libxml2.so. На этот раз пользователю на самом деле нужно открыть файл XML в emacs, поэтому emacs использует libxml2.so. Тем временем в фоне выполняются ещё два процесса, использующие ту же библиотеку. Поскольку она разделяемая, Линукс загружает один её экземпляр в физическую память и отображает его в виртуальную память всех трёх процессов.
Если вы посмотрите метрику RSS для emacs, то в неё будут включены страницы libxml2.so. RSS не врёт, потому что emacs действительно её использует, но как насчёт двух других процессов, обращающихся к библиотеке? Если вы сложите RSS всех трёх процессов, то libxml2.so будет учтена три раза, хотя в физическую память загружен только один экземпляр.
Таким образом, RSS - это индикатор для случаев, когда процесс работает один и не использует никаких функций совместно с другими процессами. На практике, где разделяемые библиотеки используются совместно, RSS будет завышать показатель памяти, потребляемой одним процессом. Эту метрику можно использовать для оценки потребления памяти, но надо иметь в виду данную особенность.
PSS (Proportional Set Size)
Индикатор PSS используется для измерения объёма памяти, потребляемой одним процессом, который делит объём памяти, потребляемой страницами разделяемых объектов, поровну между процессами, которые их используют. RSS считает объём памяти следующим образом: если N процессов используют одну разделяемую библиотеку, то каждый процесс потребляет часть памяти этой библиотеки, равную 1/N.
Например, emasc и ещё два процесса совместно используют библиотеку libxml2.so. Так как процесса три, то каждый использует 1/3 объёма памяти, занимаемой libxml2.so.
Я считаю, что PSS - более объективный индикатор, чем RSS. Особенно он подходит для учёта памяти, потребляемой всей системой, а не каждым процессом в отдельности. Например, если вы разрабатываете систему со множеством процессов и служб и хотите оценить, сколько памяти надо установить в устройство, то PSS покажет более точный результат, чем RSS.