← Позднее

Ортовремя
26 апр. 2022

Когда-то я наткнулся на статью от @bouncepaw про ортовремя.

Описание

Чтобы различать стандартную систему времени, использую приставку шайзе для текущей системы, орто для моей новой системы.

В ортовремени сутки начинаются в 0 часов. Сутки делятся на 24 часа для совместимости.

0 орточасов соответствуют 6 шайзечасам, то есть времени, когда просыпаются самые ранние жаворонки. Для сравнения, в день написания статьи я встал в 1 орточас, а за день до этого — в 2 орточаса._

У большинства людей работа начинается где-то в 3 орточаса, то есть в 9 шайзечасов. Допустим, работа длится 8 часов, до 11 орточасов. Час на дорогу, часы бьют 12 орточасов — вы дома. Прошла ровно половина суток. Всё остальное время — ваше. Делайте что хотите, можете поспать даже. А когда проснётесь, новые сутки только-только начнутся!

Как это было

Я загорелся идеей и решил попробовать, да и недавно стал носить наручные
не смарт-часы со стрелками.

Сначала это выглядело примерно так:

Кошка смотрит на часы на стене
Я пытаюсь не запутаться

Я постоянно считал, сколько сейчас шайзе-времени, вместо того, чтобы жить по орто-.
“Не тру, не канон”, - подумал я.

Решил эту проблему довольно просто. Перевёл время не только на наручных часах, но и вообще везде, где только можно, на 6 часов назад (в случае часов со стрелками + или - значения не имеют). Автоматически перенеслись все события в календаре в новые, теперь правильные, места. Стало удобно, ведь я уже не тратил усилия, чтобы переключиться с орто- на шайзе- и наоборот.

Единственное, что меня беспокоило – не все интернет-приложения работают по времени устройства (что логично из-за соображения безопасности и чего-то там ещё, но не укладывается в концепцию ортовремени). Когда ждал доставку, чуть не перепутал время и не подставил курьера, ведь: “Ну, я поменял время на телефоне, значит поменялось везде”.


прошло какое-то время спустя вышенаписанных строк

Ещё заметил, что мне, на самом деле, не так важно, сколько времени сейчас, но сколько времени до какого-либо события.
Например:
Не “мне нужно выйти из дома в 10:00”,
а “мне нужно выйти из дома через 30 минут”.

И так со мной было всегда, я просто никогда об этом раньше не задумывался.


Ещё один плюс

Тот, который я нашёл помимо тех, которые были упомянуты в статье Баунса.

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

13 месяцев * 28 дней * 364 дня. Первый день месяца - всегда воскресенье, последний день месяца - всегда суббота, один оставшийся день - Новый год

Как я собирал ядро
19 февр. 2022

У меня было 2 сисколла, 40 свободных гигов для виртуалки, 12 потоков,
Linux Kernel 5.8.1 и множество статей, инструкций и документаций всех сортов и расцветок, а также Ubuntu 20.04 LTS, vim и мои нервы. Не то что бы это был необходимый запас для сборки. Но если начал собирать ядро, становится трудно остановиться. Единственное что вызывало у меня опасение – это кернелспейс.
Нет ничего более беспомощного, безответственного и испорченного, чем студент, пытающийся разобраться в ядре Linux. Я знал, что рано или поздно закончу собирать эту дрянь.

Начинаем путешествие

Копаться в ядре стоит прежде всего на виртуальной машине. Иначе, если что-то сломается, операционная система может просто не взлететь. Ставим образ Убунты на виртуальную машину. Я делал через Boxes, ибо так проще всего.

Запускаем виртуалку и полностью её обновляем

sudo apt update && sudo apt upgrade

Скачиваем нужные пакеты для сборки ядра

sudo apt install build-essential libncurses-dev libssl-dev
 libelf-dev bison flex

Устанавливаем архив ядра

wget -P ~/Downloads/ 
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.8.1.tar.xz

Распаковываем архив ядра в домашнюю директорию

tar -xvf ~/Downloads/linux-5.8.1.tar.xz -C ~/

Пишем системный вызов

В системном вызове мне нужно достучаться до структуры pci_dev, достав любое pci-устройство, и вывести поля device и vendor в пространство пользователя.

Переходим в директорию ядра

cd ~/linux-5.8.1/

Создаём директорию с именем эквивалентному нашему системному вызову.

В моём случае нужно достать поля из структуры pci_dev. Так и назовём директорию.

mkdir pci_dev

Создаём C файл и записываем код системного вызова в него

vim pci_dev/pci_dev.c
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/pci.h>
#include <linux/uaccess.h>

// Структура, которую будем передавать в пространство пользователя
struct pci_device_info {
	unsigned short vendor_id;
	unsigned short device_id;
};

/* Объявление системного вызова (запятые в аргументах правильные).
 info: указатель на эту же структуру, но в пространстве пользователя.
*/
SYSCALL_DEFINE1(pci_dev, struct pci_device_info *, info)
{
	struct pci_dev *dev = NULL;
	struct pci_device_info dev_info;

	dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
	dev_info.device_id = dev->device;
	dev_info.vendor_id = dev->vendor;

    // Печатаем информацию о структуре в пространство ядра
	printk(KERN_INFO "pci vendor id [%d]\n", dev_info.vendor_id);
	printk(KERN_INFO "pci device id [%d]\n", dev_info.device_id);

    // Передаём структуру в пространство пользователя
	copy_to_user(info, &dev_info, sizeof(struct pci_device_info));

	return 0;
}

Сохраняем изменения и выходим из vim`а.

В той же директории создаём Makefile

vim pci_dev/Makefile

Пишем это в Makefile нашего системного вызова.

obj-y := pci_dev.o

Открываем Makefile ядра

vim Makefile

Здесь нам нужна строчка core-y с перечислением директорий а-ля kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/

Дописываем здесь директорию с нашим системным вызовом.
Должно получиться так: kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ pci_dev/

Добавляем прототип функции нашего системного вызова и структуру в заголовочный файл системных вызовов

vim include/linux/syscalls.h

В самый конец над #endif добавляем

struct pci_device_info;
asmlinkage long sys_pci_dev(struct pci_device_info *);

Добавляем запись о нашем системном вызове в таблицу системных вызовов

vim arch/x86/entry/syscalls/syscall_64.tbl

В самый конец таблицы с 64-битным системными вызовами пишем следующее.

440     common  pci_dev                sys_pci_dev

Важно соблюдать нумерацию и табы.

Установка и сборка ядра

Конфигурируем ядро

Здесь нам нужна стандартная конфигурация.

make menuconfig

Тыкаем в Save, а потом в Exit.

Узнаём, сколько у нас логических ядер

nproc

У меня их 12. Это нужно, чтобы задействовать все ядра процессора для сборки ядра операционной системы (беды с терминологией ).

Собираем ядро

make -j12

-j - с помощью этого флага указываем, сколько задач будет исполняться одновременно

Собираем модули для установки ядра

sudo make modules_install -j12

Устанавливаем ядро

sudo make install -j12

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

sudo update-grub

Перезагружаемся

reboot

Пишем программу в user-space

Теперь напишем программу, которая будет делать системный вызов и выводить в стандартный поток информацию о структуре.

Создаём C программу

vim pci_dev_user.c
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

// Определяем системный вызов для простоты
#define __NR_pci_dev 440

// Наша пользовательская структура, 
// которую будем заполнять с помощью системного вызова
struct pci_device_info {
	unsigned short vendor_id;
	unsigned short device_id;
};

// Определение функции для системного вызова
long pci_dev_syscall(struct pci_device_info *ptr)
{
	return syscall(__NR_pci_dev, ptr);
}

int main()
{
    // Инициализируем структуру для заполнения
	struct pci_device_info result = { 0 };

    // Исполняем системный вызов, в аргумент которого помещаем 
    // указатель на пользовательскую структуру
	pci_dev_syscall(&result);

    // Выводим поля структуры в стандартный поток
	printf("vendor_id: %hu\n", result.vendor_id);
	printf("device_id: %d\n", result.device_id);

	return 0;
}

Собираем программу

gcc -o pci_dev_user pci_dev_user.c

Запускаем программу

./pci_dev_user

> vendor_id: 32902
> device_id: 10688

Смотрим вывод ядра

dmesg

> [   38.604541] pci vendor id [32902]
> [   38.604544] pci device id [10688]

Работает!

То же самое, но для структуры syscall_info

Буду более краток, ибо процесс по сборке и написанию идентичный. Однако, чтобы достать структуру пришлось много потеть и прыгать от одной структуры к другой.

Системный вызов

#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/uaccess.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/sched/task_stack.h>
#include <linux/export.h>
#include <linux/types.h>

// Здесь структура очень маленькая, 
// так что просто передаём её напрямую пользователю, 
// используя определение из ptrace.h

SYSCALL_DEFINE2(syscall_info, int, pid_input, 
                struct syscall_info *, info)
{
	printk(KERN_INFO "process's pid: %d\n", pid_input);
    
	struct pid *pid_task = NULL;
	pid_task = find_get_pid(pid_input);

	struct task_struct *task = NULL;
	task = get_pid_task(pid_task, PIDTYPE_PID);

	struct syscall_info sys_info;
	task_current_syscall(task, &sys_info);

	printk(KERN_INFO "user_sp: %llu", sys_info.sp);

	copy_to_user(info, &sys_info, sizeof (struct syscall_info));

	return 0;
}

Клиентская программа

#include <linux/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define __NR_syscall_info 441

// Задаём описание структуры

struct seccomp_data {
	int nr;
	__u32 arch;
	__u64 instruction_pointer;
	__u64 args[6];
};

struct syscall_info {
	__u64 sp;
	struct seccomp_data data;
};

long syscall_info_syscall(int pid_input, struct syscall_info *ptr)
{
	return syscall(__NR_syscall_info, pid_input, ptr);
}

int main(int argc, char **argv)
{
	char *a = argv[1];
	int pid_id = atoi(a);

	printf("Pid_id: %d\n", pid_id);

	struct syscall_info result;

	syscall_info_syscall(pid_id, &result);

	printf("Syscall_number: %d\n", result.data.nr);
	printf("User Stack Pointer: %lld\n", result.sp);

	return 0;
}

Запускаем программу

Pid_id: 958
Syscall_number: 7
User Stack Pointer: 140726335318048

Смотрим вывод ядра

[   21.342638] user_sp: 140726335318048

Указатели стека идентичны, значит, структура передана верно!

Проблемы и решения

Не работает “sudo update-grub”

Изменяем конфигурацию загрузчика, чтобы загрузиться с нужным ядром

vim /etc/default/grub

Строки ниже должны быть следующими:

GRUB_DEFAULT=0
GRUB_TIMEOUT=-1 # Чтобы была возможность выбрать нужную версию ядра
GRUB_HIDDEN_TIMEOUT=0

Что-то там с сертификатами и доверенными ключами

Изменяем конфигурацию ядра.

scripts/config --disable SYSTEM_TRUSTED_KEYS

или

scripts/config --set-str SYSTEM_TRUSTED_KEYS ""

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available

sudo apt install dwarves
Эко-самурайство
07 февр. 2022
Стеклянные и пластиковые помытые бутылки стоят на балконе

С чего всё началось

Примерно год назад меня “укусила” подруга (Даша, привет!) и я начал задумываться о том, что, оказывается, можно жить немного лучше для природы, окружающей среды, планеты, бла-бла-бла…

Сразу стать супер экологичным – что-то нереальное, поэтому я решил начать с чего-то очень простого и удобного.

Первые шаги

“Чем-то очень простым и удобным” оказалась покупка шопера. Вообще, не брать пакет на кассе – это экологично и экономично. Будучи студентом, будет греховно не экономить на пакетах.

Чуть позже я обнаружил, что в Тинькофф журнале есть бесплатный курс об экологии, и быстро его прошёл. Плюсом посмотрел выпуск подкаста с Ником Чернобаевым и Романом Саблиным.

Поэтому я понял, что пытаться в экологичный образ жизни не есть что-то странное, но что-то очень простое и даже приятное.

Раздельный сбор

Недалеко от моего дома есть урны для вторсырья: пластик и стекло.

Дома у меня три “контейнера” с отходами:

Можно, конечно же, разделять пластик по типам, но мне лень.

А крышечки принимает ВкусВилл, которых полным-полно и не в центре Санкт-Петербурга.

Удобно? Удобно!

Один в поле не воин

Лучше всего – когда много людей обладают несколькими эко-привычками, чем один человек, живущий по принципу zero waste (ноль отходов). Поэтому агитация и пропаганда играет большую роль.

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

Круто? Круто!

Кофе

Я не большой любитель кофе, однако периодически пью его вне дома вместе с друзьями. Часто это случается между парами, когда совсем нет времени посидеть в кофейне: берём кофе с собой в “бумажных” стаканчиках и мчим в универ. Эти стаканчики совсем небумажные, поэтому недавно купил себе и в подарок на день рождения подруге стакан от Stojo. Классно, что он складной и очень легко моется.

Плюс во многих кофейнях Петербурга существует скидка для тех, кто приходит со своими стаканами. (Помним про бедных студентов)

Когда совсем лень

Иногда случаются моменты, когда не хочется ничего никому готовить. Здесь очень тяжело отказаться от доставки еды. Доставка еды ни разу не экологичная: эти пластиковые упаковки, пакеты, трубочки, что-то ещё…

Поэтому за меня готовит девушка я заказываю еду без столовых приборов, что всё же немного сглаживает углы.

Технологии

Также существуют сервисы технологий, сохраняющие окружающую среду.

Поисковик Ecosia получает деньги с рекламы в поисковой выдаче и вкладывает их в высаживание деревьев в Африке, Южной Америке и Азии.

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

Не забывайте быть людьми

Вечера
01 февр. 2022

Вчера, пока чистил зубы, возникла мысль, что вечера с любимым человеком нужно проводить не за просмотром очередного сериала или фильма, а просто вместе.

Когда вы что-то смотрите, вы просто занимаетесь одним и тем же делом, находясь рядом друг с другом. У одного может забита голова мыслями, у другого — просмотром, и наоборот или вообще оба будут думать о чём-то своём, а сериал будет лишь фоном, заполняющим неловкость.

Исключения составляют лишь увлечённые просмотры с последующим обменом впечатлениями, или, когда есть сильное желание что-то показать человеку.

Но вы ведь поняли меня :)
Не смотрите с любимым человеком фильмы от “нечего делать”. Лучше поговорите или просто помолчите. Вместе.

Obsidian
21 дек. 2021

Я люблю писать. Я люблю делать заметки. Да, блин, у меня даже свой блог имеется.

У меня есть определенные требования к заметочным сервисам:

Но большинство заметочных программ и сервисов мне не по душе:

Остановился я на Obsidian, в котором прямо сейчас пишу этот текст

Что же это за приложение?

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

Функции, которые мне важны и которые меня удивили:

Obsidian + Syncthing

У Obsidian есть средство синхронизации Obsidian Sync, за которое нужно платить денюжку. Однако есть несколько моментов:

Syncthing – приложение, которое позволяет синхронизировать файлы между устройствами (даже без Интернета внутри локальной сети) очень и очень просто

Чтобы мои заметки синхронизировались, я создал папку на сервере, подключил её к Syncthing. После этого я разрешил доступ к папке другим доверенным устройствам, тем самым создав папку на них. Теперь все изменения в папках отслеживаются, а данные синхронизируются. И всё бесплатно!

Правда, есть беда. Приложение Obsidian под iOS позволяет создавать заметки либо в новой папке на устройстве, либо в папке в iCloud. То есть, я не могу открыть уже существующую папку (которая синхронизируется приложением Syncthing) на устройстве. Это бесит, но что поделать, пишу заметки либо на ноутбуке, либо на компьютере, либо используя другой редактор Markdown файлов :)

Пока что всё хорошо

На данный момент – это приложение меня более, чем устраивает. Жаль, что не узнал о нём раньше, ибо прыгать с одного заметочного сервиса на другой было больно :)

Ранее →