Когда-то я наткнулся на статью от @bouncepaw про ортовремя.
Чтобы различать стандартную систему времени, использую приставку шайзе для текущей системы, орто для моей новой системы.
В ортовремени сутки начинаются в 0 часов. Сутки делятся на 24 часа для совместимости.
0 орточасов соответствуют 6 шайзечасам, то есть времени, когда просыпаются самые ранние жаворонки. Для сравнения, в день написания статьи я встал в 1 орточас, а за день до этого — в 2 орточаса._
У большинства людей работа начинается где-то в 3 орточаса, то есть в 9 шайзечасов. Допустим, работа длится 8 часов, до 11 орточасов. Час на дорогу, часы бьют 12 орточасов — вы дома. Прошла ровно половина суток. Всё остальное время — ваше. Делайте что хотите, можете поспать даже. А когда проснётесь, новые сутки только-только начнутся!
Я загорелся идеей и решил попробовать, да и недавно стал носить наручные
не смарт-часы со стрелками.
Сначала это выглядело примерно так:
Я постоянно считал, сколько сейчас шайзе-времени, вместо того, чтобы жить по орто-.
“Не тру, не канон”, - подумал я.
Решил эту проблему довольно просто. Перевёл время не только на наручных часах, но и вообще везде, где только можно, на 6 часов назад (в случае часов со стрелками + или - значения не имеют). Автоматически перенеслись все события в календаре в новые, теперь правильные, места. Стало удобно, ведь я уже не тратил усилия, чтобы переключиться с орто- на шайзе- и наоборот.
Единственное, что меня беспокоило – не все интернет-приложения работают по времени устройства (что логично из-за соображения безопасности и чего-то там ещё, но не укладывается в концепцию ортовремени). Когда ждал доставку, чуть не перепутал время и не подставил курьера, ведь: “Ну, я поменял время на телефоне, значит поменялось везде”.
прошло какое-то время спустя вышенаписанных строк
Ещё заметил, что мне, на самом деле, не так важно, сколько времени сейчас,
но сколько времени до какого-либо события.
Например:
Не “мне нужно выйти из дома в 10:00”,
а “мне нужно выйти из дома через 30 минут”.
И так со мной было всегда, я просто никогда об этом раньше не задумывался.
Тот, который я нашёл помимо тех, которые были упомянуты в статье Баунса.
Кажется, что концепция ортовремени не обязывает других ей придерживаться, чтобы перестать путаться и спокойно существовать в обществе. А вот с концепцией самого удобного в мире календаря риски ошибиться сутками или даже неделей куда критичнее, чем перепутать орто- и шайзе-часы.
У меня было 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
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`а.
vim pci_dev/Makefile
Пишем это в Makefile нашего системного вызова.
obj-y := pci_dev.o
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
Теперь напишем программу, которая будет делать системный вызов и выводить в стандартный поток информацию о структуре.
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
Указатели стека идентичны, значит, структура передана верно!
Изменяем конфигурацию загрузчика, чтобы загрузиться с нужным ядром
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 ""
sudo apt install dwarves
Примерно год назад меня “укусила” подруга (Даша, привет!) и я начал задумываться о том, что, оказывается, можно жить немного лучше для природы, окружающей среды, планеты, бла-бла-бла…
Сразу стать супер экологичным – что-то нереальное, поэтому я решил начать с чего-то очень простого и удобного.
“Чем-то очень простым и удобным” оказалась покупка шопера. Вообще, не брать пакет на кассе – это экологично и экономично. Будучи студентом, будет греховно не экономить на пакетах.
Чуть позже я обнаружил, что в Тинькофф журнале есть бесплатный курс об экологии, и быстро его прошёл. Плюсом посмотрел выпуск подкаста с Ником Чернобаевым и Романом Саблиным.
Поэтому я понял, что пытаться в экологичный образ жизни не есть что-то странное, но что-то очень простое и даже приятное.
Недалеко от моего дома есть урны для вторсырья: пластик и стекло.
Дома у меня три “контейнера” с отходами:
Можно, конечно же, разделять пластик по типам, но мне лень.
А крышечки принимает ВкусВилл, которых полным-полно и не в центре Санкт-Петербурга.
Удобно? Удобно!
Лучше всего – когда много людей обладают несколькими эко-привычками, чем один человек, живущий по принципу zero waste (ноль отходов). Поэтому агитация и пропаганда играет большую роль.
Например, в жилом комплексе, где я живу, есть крутая акция. В заранее обозначенные дни к нам приезжает грузовик и забирает макулатуру, некоторые фракции пластика и крышечки. За собранное вторсырьё мы получаем баллы, которые обмениваем на саженцы для благоустройства двора нашего ЖК. Судя по сообщениям в чатиках и группе, людей приходит всё больше и больше. Значит, инициатива работает.
Круто? Круто!
Я не большой любитель кофе, однако периодически пью его вне дома вместе с друзьями. Часто это случается между парами, когда совсем нет времени посидеть в кофейне: берём кофе с собой в “бумажных” стаканчиках и мчим в универ. Эти стаканчики совсем небумажные, поэтому недавно купил себе и в подарок на день рождения подруге стакан от Stojo. Классно, что он складной и очень легко моется.
Плюс во многих кофейнях Петербурга существует скидка для тех, кто приходит со своими стаканами. (Помним про бедных студентов)
Иногда случаются моменты, когда не хочется ничего никому готовить. Здесь очень тяжело отказаться от доставки еды. Доставка еды ни разу не экологичная: эти пластиковые упаковки, пакеты, трубочки, что-то ещё…
Поэтому за меня готовит девушка я заказываю еду без столовых приборов, что всё же немного сглаживает углы.
Также существуют сервисы технологий, сохраняющие окружающую среду.
Поисковик Ecosia получает деньги с рекламы в поисковой выдаче и вкладывает их в высаживание деревьев в Африке, Южной Америке и Азии.
Ещё хорошим примером служит хостинг-провайдер Hetzner, который использует энергию из возобновляемых источников для питания своих серверов.
Вчера, пока чистил зубы, возникла мысль, что вечера с любимым человеком нужно проводить не за просмотром очередного сериала или фильма, а просто вместе.
Когда вы что-то смотрите, вы просто занимаетесь одним и тем же делом, находясь рядом друг с другом. У одного может забита голова мыслями, у другого — просмотром, и наоборот или вообще оба будут думать о чём-то своём, а сериал будет лишь фоном, заполняющим неловкость.
Исключения составляют лишь увлечённые просмотры с последующим обменом впечатлениями, или, когда есть сильное желание что-то показать человеку.
Но вы ведь поняли меня :)
Не смотрите с любимым человеком фильмы от “нечего делать”.
Лучше поговорите или просто помолчите. Вместе.
Я люблю писать. Я люблю делать заметки. Да, блин, у меня даже свой блог имеется.
У меня есть определенные требования к заметочным сервисам:
Но большинство заметочных программ и сервисов мне не по душе:
Остановился я на Obsidian, в котором прямо сейчас пишу этот текст
Obsidian по сути есть очень крутой редактор самых обычных Markdown файлов, с помощью которого можно создать личную базу знаний или, если угодно, личную вики
Функции, которые мне важны и которые меня удивили:
У Obsidian есть средство синхронизации Obsidian Sync, за которое нужно платить денюжку. Однако есть несколько моментов:
Syncthing – приложение, которое позволяет синхронизировать файлы между устройствами (даже без Интернета внутри локальной сети) очень и очень просто
Чтобы мои заметки синхронизировались, я создал папку на сервере, подключил её к Syncthing. После этого я разрешил доступ к папке другим доверенным устройствам, тем самым создав папку на них. Теперь все изменения в папках отслеживаются, а данные синхронизируются. И всё бесплатно!
Правда, есть беда. Приложение Obsidian под iOS позволяет создавать заметки либо в новой папке на устройстве, либо в папке в iCloud. То есть, я не могу открыть уже существующую папку (которая синхронизируется приложением Syncthing) на устройстве. Это бесит, но что поделать, пишу заметки либо на ноутбуке, либо на компьютере, либо используя другой редактор Markdown файлов :)
На данный момент – это приложение меня более, чем устраивает. Жаль, что не узнал о нём раньше, ибо прыгать с одного заметочного сервиса на другой было больно :)